Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I've added the various suggestions in this thread: using bind_columns and prepare_cached from perrin, the use of XML::LibXML::SAX::Builder to avoid creating a temporary string, and using matts' new XML::Generator::DBI version to take advantage of the sth handler. I've also added code that uses XML::XSLT, which surprising is VERY bad at least as I've used it (did I use it wrong? I couldn't get a pure XML DOM document to work with it...)

The results are:

XML and XSLT, String Intermediate, XML::XSLT 0.159/s + -- -62% -88% -94% -95% -96% -99% + -100% XML and TT2/XPath 0.422/s + 166% -- -67% -84% -87% -90% -98% - +100% XML and TT2/Simple 1.29/s + 713% 205% -- -51% -60% -69% -95% - +99% XML and XSLT, String Intermediate, LibXSLT 2.66/s + 1573% 529% 106% -- -17% -36% -90% - +98% XML and XSLT, XML Intermediate, LibXSLT 3.20/s + 1915% 657% 148% 20% -- -23% -87% - +98% DBI and TT2 4.13/s + 2505% 879% 221% 56% 29% -- -84% - +98% DBI and CGI 25.4/s + 15931% 5924% 1873% 858% 696% 516% -- - +85% DBI and Print 172/s + 108526% 40717% 13269% 6391% 5291% 4071% 578% - +-
Nothing surprising about the order, but as you can see, with the various improvements, the behavior of LibXSLT getting close to that of DBI and TT2. There may be other improves that one could do, but as it stands, I think some of the benefits of using XSLT can outweight the small performance penalty compared to TT2 usage.

Except for changing the XSLT template as Matts indicated, the rest of the files remain unchanged. Here's the updated test code, however...

#!/usr/bin/perl -w use strict; use DBI; use CGI qw/-no_xhtml :standard/; use XML::Generator::DBI; use XML::Handler::YAWriter; use XML::LibXML::SAX::Builder; use XML::LibXML; use XML::LibXSLT; use XML::XSLT; use Template; use Data::Dumper; use Benchmark qw( cmpthese ); $Template::Config::STASH = 'Template::Stash'; my $dbh = DBI->connect( "dbi:Pg:dbname=monksdb", "", "" ) or die $DBI::errstr; my $query = "SELECT id, name, xp, lat, long FROM monks ORDER BY lat LI +MIT 25"; my $sth = $dbh->prepare_cached( $query ) or die $DBI::errstr; my $ya = XML::Handler::YAWriter->new( AsString => 1 ); my $generator = XML::Generator::DBI->new( Handler => $ya, dbh => $dbh, RowElement => "monk" ); my $generator2 = XML::Generator::DBI->new( Handler => XML::LibXML::SAX::Builder->new(), dbh => $dbh, RowElement => "monk" ); my $tt2 = Template->new; my $tt2_nonXML = "template1.tt2"; my $tt2_XML = "template2.tt2"; my $tt2_XPath = "template3.tt2"; my $parser = new XML::LibXML; my $xslt = new XML::LibXSLT; my $sheet = "xslt_sheet.xsl"; my $slt = $parser->parse_file( $sheet ); my $stylesheet = $xslt->parse_stylesheet( $slt ); my $stylesheet2 = XML::XSLT->new( $sheet, warnings => 1 ); open FILE, ">/dev/null" or die "Cannot write out: $!"; my $target = \*FILE; cmpthese( 100, { "DBI and Print" => \&generate_from_straight_dbi_and_print, "DBI and CGI" => \&generate_from_straight_dbi_and_cgi, "DBI and TT2" => \&generate_from_straight_dbi_and_tt2, "XML and TT2/Simple" => \&generate_from_xml_and_tt2_and_xmlsimp +le, "XML and TT2/XPath" => \&generate_from_xml_and_tt2_and_xpath, "XML and XSLT, String Intermediate, LibXSLT " => \&generate_fro +m_xml_and_xslt_string, "XML and XSLT, XML Intermediate, LibXSLT" => \&generate_from_xm +l_and_xslt_xml, "XML and XSLT, String Intermediate, XML::XSLT" => \&generate_fr +om_xmlxslt_xml } ); close FILE; # Here, we use straight DBI calls and print calls to mark up # the table sub generate_from_straight_dbi_and_print { # my $target = shift; $sth->execute() or die $DBI::errstr; my ( $id, $name, $xp, $lat, $long ); $sth->bind_columns( \$id, \$name, \$xp, \$lat, \$long ); print $target "Content-Type: text/html\n\n"; print $target "<html><body><table>\n"; my $colorrow = 0; while ( $sth->fetch() ) { $colorrow = !$colorrow; my $color = ( $colorrow ) ? "#FFFFFF" : "#D0D0FF"; print $target <<ROW; <tr> <td bgcolor="$color">$id</td> <td bgcolor="$color">$name</td> <td bgcolor="$color">$xp</td> <td bgcolor="$color">$lat</td> <td bgcolor="$color">$long</td> </tr> ROW ; } print $target "</table></body></html>"; } # Here, we group the results as to make it easier for CGI # to print out (avoiding large HERE docs...) sub generate_from_straight_dbi_and_cgi { # my $target = shift; $sth->execute() or die $DBI::errstr; my ( $id, $name, $xp, $lat, $long ); $sth->bind_columns( \$id, \$name, \$xp, \$lat, \$long ); my @data; while ( $sth->fetch ) { push @data, [$id, $name, $xp, $lat, $long]; +} my $colorrow = 0; print $target header('text/html'), start_html, table( map { $colorrow = !$colorrow; my $color = ( $colorrow ) ? "#FFFFFF" : "#D0D0FF"; Tr( td( {-bgcolor=>$color}, $_ ) ) } @data ), end_html; } # Here, we pass the results to Template Toolkit for printing sub generate_from_straight_dbi_and_tt2 { # my $target = shift; $sth->execute() or die $DBI::errstr; my ( $id, $name, $xp, $lat, $long ); $sth->bind_columns( \$id, \$name, \$xp, \$lat, \$long ); my @data; while ( $sth->fetch ) { push @data, [$id, $name, $xp, $lat, $long]; +} print $target header; $tt2->process( $tt2_nonXML, { monks => \@data }, $target ) or die $tt2->error(),"\n"; } # Use TT2 again, but now pass it XML and use the XPath module # for parsing sub generate_from_xml_and_tt2_and_xmlsimple { # my $target = shift; my $xml = $generator->execute( $query ); print $target header; $tt2->process( $tt2_XML, { results => $xml }, $target ) or die $tt2->error(), "\n"; } # Use TT2 again, but now pass it XML and use the XPath module # for parsing sub generate_from_xml_and_tt2_and_xpath { # my $target = shift; my $xml = $generator->execute( $query ); print $target header; $tt2->process( $tt2_XPath, { results => $xml }, $target ) or die $tt2->error(), "\n"; } # Use LibXML/LibXSLT to parse the results sub generate_from_xml_and_xslt_string { # my $target = shift; my $xml = $generator->execute( $sth ); print $target header; my $source = $parser->parse_string( $xml ); my $results = $stylesheet->transform( $source ); print $target $stylesheet->output_string( $results ); } sub generate_from_xml_and_xslt_xml { # my $target = shift; my $xml = $generator2->execute( $sth ); print $target header; my $results = $stylesheet->transform( $xml ); print $target $stylesheet->output_string( $results ); } sub generate_from_xmlxslt_xml { # my $target = shift; my $xml = $generator->execute( $sth ); print $target header; print $target $stylesheet2->serve( $xml ); }

-----------------------------------------------------
Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
"I can see my house from here!"
It's not what you know, but knowing how to find it if you don't know that's important


In reply to (Updates) Re: XSLT vs Templating, Part 2 by Masem
in thread XSLT vs Templating, Part 2 by Masem

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2024-03-28 10:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found