Here is a very very simple script comparing three
approaches to build a large html table. I was surprised to
see TT2 being the fastest..run it yourself and see.
Note that XSLT timings include the time to build XML data
string since in real life all data comes from Relational 
Database that must be converted into XML string and parsed.

Of course, it tests only the Looping construct, not
INCLUDE/PROCESS and various other features.

############################START#################
#!/usr/bin/perl
use strict;
use Time::HiRes qw(gettimeofday tv_interval);
use Data::Dumper;
use XML::LibXML;
use XML::LibXSLT;
use HTML::Template;
use Template;
use File::Temp qw(tmpnam);


my ($xslt_timer, $html_timer, $tt2_timer);
my ($xml_parser, $xsl_parser) = (XML::LibXML->new,
XML::LibXSLT->new);

my $big_array = build_big_array(5000);
my $xml_data = build_xml_data($big_array);
my $template_obj = build_html_template();
my $html3 = render_tt2($big_array);
my $xsl = build_xsl_processor();

my $html1 = render_html_template($template_obj,
$big_array);
my $html2 = render_xslt($xsl, $xml_data );

save_output($html1, $html2, $html3);
print<<EOK;
HTML Template Time : $html_timer
XSLT Time          : $xslt_timer
TT2 Time           : $tt2_timer
EOK

sub build_big_array
{
    my $count = shift;
    my $data = _read_chunk ('data');
    my @big_array;
    my $h = eval $data;
    for (my $i=0 ; $i < $count; $i++) { push (@big_array,
$h); }
    return [EMAIL PROTECTED];
}

sub build_xml_data
{
    my $data_array = shift;
    my $t0 = [gettimeofday];
    my $xml_data = "<results>";
    foreach my $data (@$data_array)
    {
        $xml_data .= "<r>\n";
        foreach my $k (keys %$data)
        {
            $xml_data .=
"<$k><![CDATA[$data->{$k}]]></$k>\n";
        }
        $xml_data .= "</r>\n";
    }
    $xml_data .= "</results>";
    #print "$xml_data\n";
    my $dom = $xml_parser->parse_string($xml_data);
    $xslt_timer += tv_interval($t0, [gettimeofday]);
    return $dom;
}

sub build_xsl_processor
{
    my $str = _read_chunk ('xsl');
    my $xsl = $xml_parser->parse_string ($str);
    return $xsl_parser->parse_stylesheet($xsl);
}

sub build_html_template
{
    my $tmpl = _read_chunk ('template');
    return HTML::Template->new( scalarref => \$tmpl );
}

sub _read_chunk
{
    my $starter = shift;
    my ($running, $stop, $data) = (0,0);
    while (<DATA>)
    {
        next unless (/^\$$starter/ || $running);
        $running = 1;
        chomp;
        s/^\s+//;
        s/\s+$//;
        next if /^\$$starter/;
        $stop++ if length($_) == 0;
        last if $stop == 2;
        $data .= $_;
    }
    return $data;
}

sub render_html_template
{
    my ($template_obj, $data) = @_;
    my $t0 = [gettimeofday];
    $template_obj->param(TR_LOOP => $data);
    my $html= $template_obj->output;
    $html_timer += tv_interval($t0, [gettimeofday]);
    return $html;
}

sub render_xslt
{
    my $xsl_proc = shift;
    my $xml_dom = shift;
    # timer starts here
    my $t0 = [gettimeofday];
    my $html =
$xsl_proc->output_string($xsl_proc->transform($xml_dom));
    $xslt_timer += tv_interval($t0, [gettimeofday]);
    return $html;
}

sub render_tt2
{
    my ($data) = @_;
    my $o_tt2 = Template->new({
                                ABSOLUTE => 1,
                              });
    my $templ = _read_chunk('tt_template');
    my $filename =  tmpnam();
    open (F, ">$filename");
    print F $templ;
    close F;

    my $str;
    $o_tt2->process($filename,{data => $data},\$str);

    # need to process twice since first one would  not use
cached template
    my $str_new;
    my $t0 = [gettimeofday];
    unless ($o_tt2->process($filename,{data =>
$data},\$str_new))
    {
        print STDERR "TT2 ERROR ",$o_tt2->error(),"\n";
    }
    $tt2_timer += tv_interval($t0);
    unlink $filename;
    return $str_new;
}

sub save_output
{
    my ($h1, $h2, $h3) = @_;
    open (F, ">html_template.html") ;
    print F $h1,"\n" ;
    close F;

    open (F, ">html_xslt.html");
    print F $h2,"\n" ;
    close F;

    open (F, ">html_tt2.html");
    print F $h3,"\n" ;
    close F;
}

__DATA__
$data=
{
         id => 100,
         p_name => 'JOHN',
         ap_time => '20050324 18-24-00',
         ap_tzr => 'US/Eastern',
         ap_tzra => 'EST',
         p_id => 109,
         ap_phone => '617 249 5000',
         ap => 'John Hopkins',
         ap_loc => 'Washington DC',
         ct_time => '20050405 10-32-00',
         ct_tzr => 'US/Pacific',
         ct_tzra => 'PST',
         count => 5,
}


$template=
<html><body>
<table tabindex='16' cellspacing='0' id='results_tbl'
style='width:100%;margin:0px;margin-top:1px;padding:0px;'
cellpadding='0' class='apptstable sort-table' >
<thead><tr><th>ID</th><th>Patient Name</th><th
style=''>Appt Time</th><th style=''>App Timezone</th><th
style=''>Timezone</th><th style=''>Patient ID</th><th
style=''>Appt Phone</th><th>Appt Prov</th><th>Appt
Location</th><th>Call
Time</th><th>Timezone</th><th>Timezone</th><th>Count</th></tr></thead>
<tbody>
<TMPL_LOOP NAME='TR_LOOP'>
<tr onmouseover='_results_tbl.rollOver(this);'
onmouseout='_results_tbl.rollOut(this);'
ondblclick='_results_tbl.dblclick(this);'
onclick='_results_tbl.click({rowObject:this},
_results_tbl);'>
<td title='id'><TMPL_VAR NAME='id'></td>
<td title='p_name'><TMPL_VAR NAME='p_name'></td>
<td title='ap_time'><TMPL_VAR NAME='ap_time'></td>
<td title='ap_tzr'><TMPL_VAR NAME='ap_tzr'></td>
<td title='ap_tzra'><TMPL_VAR NAME='ap_tzra'></td>
<td title='p_id'><TMPL_VAR NAME='p_id'></td>
<td title='ap_phone'><TMPL_VAR NAME='ap_phone'></td>
<td title='ap'><TMPL_VAR NAME='ap'></td>
<td title='ap_loc'><TMPL_VAR NAME='ap_loc'></td>
<td title='ct_time'><TMPL_VAR NAME='ct_time'></td>
<td title='ct_tzr'><TMPL_VAR NAME='ct_tzr'></td>
<td title='ct_tzra'><TMPL_VAR NAME='ct_tzra'></td>
<td title='count'><TMPL_VAR NAME='count'></td>
</tr>
</TMPL_LOOP>
</table>
</body></html>


$tt_template=
<html><body>
<table tabindex='16' cellspacing='0' id='results_tbl'
style='width:100%;margin:0px;margin-top:1px;padding:0px;'
cellpadding='0' class='apptstable sort-table' >
<thead><tr><th>ID</th><th>Patient Name</th><th
style=''>Appt Time</th><th style=''>App Timezone</th><th
style=''>Timezone</th><th style=''>Patient ID</th><th
style=''>Appt Phone</th><th>Appt Prov</th><th>Appt
Location</th><th>Call
Time</th><th>Timezone</th><th>Timezone</th><th>Count</th></tr></thead>
<tbody>
[% FOREACH tr=data %]
<tr onmouseover='_results_tbl.rollOver(this);'
onmouseout='_results_tbl.rollOut(this);'
ondblclick='_results_tbl.dblclick(this);'
onclick='_results_tbl.click({rowObject:this},
_results_tbl);'>
<td title='id'>[% tr.id %]</td>
<td title='p_name'>[% tr.p_name %]></td>
<td title='ap_time'>[% tr.ap_time %]</td>
<td title='ap_tzr'>[% tr.ap_tzr %]</td>
<td title='ap_tzra'>[% tr.ap_tzra %]</td>
<td title='p_id'>[% tr.p_id %]</td>
<td title='ap_phone'>[% tr.ap_phone %]</td>
<td title='ap'>[% tr.ap %]</td>
<td title='ap_loc'>[% tr.ap_loc %]</td>
<td title='ct_time'>[% tr.ct_time %]</td>
<td title='ct_tzr'>[% tr.ct_tzr %]</td>
<td title='ct_tzra'>[% tr.ct_tzra %]</td>
<td title='count'>[% tr.count %]</td>
</tr>
[% END %]
</table>
</body></html>


$xsl=
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

        <xsl:output method="html"/>
        <xsl:template match="/">
                <xsl:element name='html'>
                <xsl:element name='body'>
                <xsl:element name="table">
                        <xsl:attribute
name="id">results_table</xsl:attribute>
                        <xsl:attribute
name="class">statstabledata sort-table</xsl:attribute>
                        <xsl:element name="thead">
                                <xsl:element name="tr">
                                        <xsl:element
name="th">
                                               
<xsl:text>ID</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Patient Name</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Appt Time</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>App Timezone</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Timezone</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Patient ID</xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Appt Phone </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Appt Prov </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Appt Location </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Call Time </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Timezone </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Timezone </xsl:text>
                                        </xsl:element>
                                        <xsl:element
name="th">
                                               
<xsl:text>Count </xsl:text>
                                        </xsl:element>
                                </xsl:element>
                        </xsl:element>
                        <xsl:element name="tbody">
                                <xsl:for-each
select="results/r">
                                        <xsl:element
name="tr">
                                               
<xsl:attribute name="onmouseover">
                                                       
<xsl:text>_resp.tableSelect.rollOver(this);</xsl:text>
                                               
</xsl:attribute>
                                               
<xsl:attribute name="onmouseout">
                                                       
<xsl:text>_resp.tableSelect.rollOut(this);</xsl:text>
                                               
</xsl:attribute>
                                               
<xsl:attribute name="ondblclick">
                                                       
<xsl:text>_resp.tableSelect.dblclick(this);</xsl:text>
                                               
</xsl:attribute>
                                               
<xsl:attribute name="onclick">
                                                       
<xsl:text>_resp.tableSelect.click({rowObject:this},
_resp.tableselect);</xsl:text>
                                               
</xsl:attribute>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>id</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="id"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>p_name</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="p_name"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap_time</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap_time"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap_tzr</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap_tzr"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap_tzra</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap_tzra"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>p_id</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="p_id"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap_phone</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap_phone"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ap_loc</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ap_loc"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ct_time</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ct_time"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ct_tzr</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ct_tzr"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>ct_tzra</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="ct_tzra"/>
                                               
</xsl:element>
                                               
<xsl:element name="td">
                                               
<xsl:attribute name='title'>
                                                       
<xsl:text>count</xsl:text>
                                               
</xsl:attribute>
                                                       
<xsl:value-of select="count"/>
                                               
</xsl:element>
                                        </xsl:element>
                                </xsl:for-each>
                        </xsl:element>
                </xsl:element>
                </xsl:element>
                </xsl:element>
        </xsl:template>
</xsl:stylesheet>


########################### __END__



--- Perrin Harkins <[EMAIL PROTECTED]> wrote:

> On Fri, 2005-09-09 at 14:38 -0400, Matt Sergeant wrote:
> > Yes I know that's what you're saying. I'm just saying
> I'd be willing to 
> > bet it's the other way around (even when compared with
> HT::JIT).
> 
> I'd wager a pint on this.  We could make it a lightning
> talk at next
> year's YAPC::NA.
> 
> - Perrin
> 
> 


  - Praveen  

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Reply via email to