in reply to Re: RFC: Templating without a System
in thread RFC: Templating without a System

Not exactly if I look at speed.

DOM parsing is costly, I have considered that approach, but I would do it only in the design phase of the application and deployment, or after changes made to some template, its to say I wouldn't use it as the page generating core.

I ran benchmark on a 5649 Byte html file with HTML::Seamstress and Servlet.

The only changes were uncomment use warnings because it clutters up the test with warnings about unitialized variables, and changed the warn "PROCESS_TREE: ", $tree->as_HTML; to a print statement.
No replace_content at all.

bench.pl:

#!/usr/bin/perl use lib "."; use Benchmark qw(:all) ; use Servlet qw(servlet); use example; # the spkg.pl generated package open(O,">/dev/null"); select O; # initialize some empty references I need in example.al my $freelist = []; my $list = []; my $in = {}; my $r = example->new; my $s = servlet( in => 'example.html', args => [ qw($nm $list $em8 $error $in $scopename $ref $res +ult $em26 $link $freelist $networkname $em14 $em9 %oui) ], ); my $count = 10000; my $results = timethese($count, { 'Seamstress' => sub { $r->process() }, 'Servlet' => sub { $s->($nm, $list, $em8, $error, $in, $scopena +me, $ref, $result, $em26, $link, $freelist, $networkname, $em14, $em9 +, %oui) }, }); select STDOUT; cmpthese($results);
gave the following results:
Rate Seamstress Servlet Seamstress 242/s -- -99% Servlet 47619/s 19548% --
I would replace_content with variable stubs and turn the resulting file inside out, as with my code.

greetings,
--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^3: RFC: Templating without a System
by metaperl (Curate) on Jun 23, 2006 at 13:46 UTC
    Thank you for giving HTML::Seamstress serious consideration. I too was worried about performance at production level... what I did was pre-parse the HTML file before each web request.

    I looked around on CPAN for a singleton caching solution, but nothing really fit, so what I did was call Webpage::PackageName->new() and store the results in a cache key ahead of time. The module for caching is Class::Cache. Like I said, I didn't want to write it but it was necessary.

      As you may have seen from my benchmarking code I was not re-parsing the HTML, every time round, but only calling process with a pre-parsed tree.

      You're in a fix here.

      Parsing HTML to a DOM tree gives you the freedom to manipulate every branch and twig and content as you like, but at the cost of speed. If you cache the modified tree or parts of it, you give away that freedom, as if you hadn't had it in the first place.

      If if you have fixed places where elements are altered - as with your example pages produced from spkg.pl, there is no difference to static pages with inline perl as with Mason or with my approach.

      In the sub process of spkg.pl-generated pages the names are even static:

      sub process { my ($tree, $c, $stash) = @_; use Data::Dumper; warn "PROCESS_TREE: ", $tree->as_HTML; # $tree->look_down(id => $_)->replace_content($stash->{$_}) # for qw(name date); $tree; }

      To have freedom of which node has to be altered with which value, the key/value pairs should be taken from $stash. But then, again, caching is ineffective.

      That's why I think HTML::Seamstress is ok for template generation but not actually for serving pages.

      regards,
      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}