On Thursday 11 May 2006 12:01 pm, Perrin Harkins wrote:
> On Thu, 2006-05-11 at 10:23 -0600, Paul Seamons wrote:
> > The benchmark_template.pl was sent as a reply to that same thread.  But
> > to make things easy here it is again - and with the results as an
> > attachment (the results are also embedded in the benchmark_template.pl).
>
> I can't tell what this first column (where results are closest) is.  It
> says "New object each time (undef CACHE_SIZE)" but it can't be making a
> new object each time, since it has the best performance.

Yes - I noticed that.  The headers on the first and second columns are indeed 
reversed.  The first column is the cached in memory.  The last column which 
has the iterations per second is the performance of CET cached in memory.  So 
the second column would be the new object each time.

> It looks like file_TT() in your benchmark does what I would expect
> someone who cares about the performance to do, i.e. keep a TT object
> around so it can cache.  Was it using the XS stash in the run that gave
> these numbers?

The numbers represent not use the Stash::XS.  There are two lines in the 
bench_template.pl that will enable Stash::XS if uncommented.  I just ran the 
entire test suite and am including the numbers as an attachment.

> Have you tried any longer templates?

The "$longer" variable in test 48_complex uses a little bit longer template 
that combines includes, foreach loops and variable accesses.  It looks like 
this:

my $longer_template = "[% INCLUDE bar.tt %]"
    ."[% array.join('|') %]"
    .("123"x200)
    ."[% FOREACH a IN array %]foobar[% IF a == 'A' %][% INCLUDE baz.tt %][% 
END %]bazbing[% END %]"
    .("456"x200)
    ."[% IF foo ; bar ; ELSIF baz ; bing ; ELSE ; bong ; END %]"
    .("789"x200)
    ."[% IF foo ; bar ; ELSIF baz ; bing ; ELSE ; bong ; END %]"
    .("012"x200)
    ."[% IF foo ; bar ; ELSIF baz ; bing ; ELSE ; bong ; END %]"
    ."[% array.join('|') %]"
    ."[% PROCESS bar.tt %]";

It isn't overly complex - but will start to show more of a normal sized 
template performance.  The numbers for that test are:

#   51%  #  305%  #  139%  #  264%  # 1098.6/s # without XS
#   -6%  #  273%  #   99%  #  232%  # 1046.3/s # with XS

So it is only 50% faster on the cached in memory templates.  It is actually 
slower if you are using XS.  If you are using cached in memory templates, you 
are going to see the least amount of return from using CGI::Ex::Template.

The interesting thing is that TT in memory and using XS is only 100% faster 
than CGI::Ex::Template getting a new object each time.  Without XS, TT in 
memory is only 40% faster than CGI::Ex::Template getting a new object each 
time.

> Sure, but since the primary reason I'd consider switching to using your
> module is the performance, it is pretty important to know if it's likely
> to really be faster or not.

Relatively - it appears to.  Your mileage may vary.

I don't know that I would actively evangelize people to use CGI::Ex::Template 
over Template::Toolkit.  If you are using mod_perl and pre-caching your 
templates - there may not be too big a reason for using CGI::Ex::Template.  I 
hope more that CGI::Ex::Template may be more of a reason for those not using 
TT syntax to use it.  CGI::Ex::Template squashes some of the excuses I've 
heard for not using TT (of course people can make up more).  TT as a 
mini-language seems to be perfect.

There will certainly be people using Template::Document or Parser or Provider 
or their own stash who will certainly need to stay with Template::Toolkit so 
all of this is moot to them.

> Do you have support for TT plugins or equivalents for any of the common
> ones?

Most of the built in TT plugins work (I'm not aware of ones that don't - but 
any of them that rely too heavily on the TT internals will have problems - 
I've added compatibility for the others).  The only issue is that some 
plugins don't "use Template::Exception" but throw Template::Exceptions.  
CGI::Ex::Template uses CGI::Ex::Template::Exception.  You'll need to "use 
Template::Exception" explicitly on some of these.

The USE directive should work the same as TT, except that if you change the 
PLUGIN_BASE CGI::Ex::Template won't try and fallback to Template::Plugin if 
the module wasn't found.  PLUGIN_BASE defaults to Template::Plugin and works 
just fine for normal Template plugins.  LOAD_PERL, PLUGINS, PLUGIN_FACTORY 
also work just fine.

Paul
#                                                                         ### 
All percents are CGI::Ex::Template vs TT2
#                                                                         ### 
(The percent that CET is faster than TT)
#                                                                               
Existing object by string ref #
#                                                                      New 
object with CACHE_EXT set #        #
#                                       This percent is compiled in memory 
(repeated calls) #        #        #
#                                          New object each time (undef 
CACHE_SIZE) #        #        #        #
my $tests = {                                                             #     
   #        #        #        #
    '01_empty'     => "",                                                 #  
161%  #  608%  #  299%  #  378%  # 18478.0/s #
    '02_var_sma'   => "[% one %]",                                        #   
99%  #  550%  #  388%  #  419%  # 13771.3/s #
    '03_var_lar'   => "[% one %]"x100,                                    #  
-71%  #  326%  #   10%  #  317%  # 907.7/s #
    '04_set_sma'   => "[% SET one = 2 %]",                                #   
93%  #  501%  #  379%  #  362%  # 13272.7/s #
    '05_set_lar'   => "[% SET one = 2 %]"x100,                            #  
-74%  #  260%  #  -13%  #  258%  # 836.4/s #
    '06_set_range' => "[% SET one = [0..30] %]",                          #    
7%  #  302%  #  229%  #  187%  # 7191.0/s #
    '07_chain_sm'  => "[% hash.a %]",                                     #   
89%  #  562%  #  394%  #  420%  # 12615.0/s #
    '08_mixed_sma' => "".((" "x100)."[% one %]\n")x10,                    #   
-4%  #  479%  #  208%  #  434%  # 5607.7/s #
    '09_mixed_med' => "".((" "x10)."[% one %]\n")x100,                    #  
-71%  #  401%  #   53%  #  394%  # 824.9/s #
    '10_str_sma'   => "".("[% \"".(" "x100)."\$one\" %]\n")x10,           #  
-55%  #  1372%  #   70%  #  1443%  # 2563.1/s #
    '11_str_lar'   => "".("[% \"".(" "x10)."\$one\" %]\n")x100,           #  
-88%  #  283%  #  -26%  #  282%  # 307.8/s #
    '12_num_lterl' => "[% 2 %]",                                          #  
120%  #  566%  #  423%  #  423%  # 15244.2/s #
    '13_plus'      => "[% 1 + 2 %]",                                      #   
45%  #  425%  #  313%  #  264%  # 10232.5/s #
    '14_plus_long' => "[% 1 + 2 + 3 + 5 + 6 + 8 %]",                      #   
30%  #  312%  #  273%  #  196%  # 9173.7/s #
    '15_chained'   => "[% c.d.0.hee.0 %]",                                #   
94%  #  587%  #  376%  #  493%  # 13048.1/s #
    '16_chain_set' => "[% SET c.d.0.hee.0 = 2 %]",                        #   
60%  #  476%  #  309%  #  350%  # 10095.3/s #
    '17_chain_lar' => "[% c.d.0.hee.0 %]"x100,                            #  
-57%  #  428%  #   22%  #  429%  # 718.2/s #
    '18_chain_sl'  => "[% SET c.d.0.hee.0 = 2 %]"x100,                    #  
-69%  #  293%  #  -22%  #  301%  # 329.3/s #
    '19_cplx_comp' => "[% t = 1 || 0 ? 0 : 1 || 2 ? 2 : 3 %][% t %]",     #   
21%  #  272%  #  223%  #  189%  # 8215.6/s #
    '20_if_sim_t'  => "[% a=1 %][% IF a %]Two[% END %]",                  #   
59%  #  452%  #  304%  #  347%  # 10597.7/s #
    '21_if_sim_f'  => "         [% IF a %]Two[% END %]",                  #   
96%  #  592%  #  391%  #  444%  # 13372.6/s #
    '22_if_else'   => "[% IF a %]A[% ELSE %]B[% END %]",                  #   
79%  #  504%  #  348%  #  404%  # 12279.7/s #
    '23_if_elsif'  => "[% IF a %]A[% ELSIF b %]B[% ELSE %]C[% END %]",    #   
61%  #  480%  #  320%  #  378%  # 10911.0/s #
    '24_for_i_sml' => "[% FOREACH i = [0..10]   ; i ; END %]",            #  
-32%  #  196%  #  108%  #  121%  # 2312.7/s #
    '25_for_i_med' => "[% FOREACH i = [0..100]  ; i ; END %]",            #  
-61%  #   -4%  #  -31%  #  -24%  # 352.5/s #
    '26_for_sml'   => "[% FOREACH [0..10]       ; i ; END %]",            #  
-25%  #  208%  #  117%  #  129%  # 2345.9/s #
    '27_for_med'   => "[% FOREACH [0..100]      ; i ; END %]",            #  
-57%  #    0%  #  -27%  #  -19%  # 372.9/s #
    '28_while'     => "[% f = 10 %][%WHILE f%][%f=f- 1%][%f%][% END %]",  #  
-73%  #  105%  #   -3%  #   53%  # 1226.9/s #
    '29_whl_set_l' => "[% f = 10; WHILE (g=f) ; f = f - 1 ; f ; END %]",  #  
-76%  #   69%  #  -18%  #   28%  # 968.5/s #
    '30_whl_set_s' => "[% f = 1;  WHILE (g=f) ; f = f - 1 ; f ; END %]",  #  
-22%  #  275%  #  161%  #  206%  # 4824.3/s #
    '31_file_proc' => "[% PROCESS bar.tt %]",                             #  
161%  #  547%  #  364%  #  446%  # 9953.2/s #
    '32_file_incl' => "[% INCLUDE baz.tt %]",                             #   
84%  #  432%  #  263%  #  304%  # 6356.3/s #
    '33_process'   => "[% BLOCK foo %]Hi[% END %][% PROCESS foo %]",      #   
86%  #  547%  #  378%  #  447%  # 9570.1/s #
    '34_include'   => "[% BLOCK foo %]Hi[% END %][% INCLUDE foo %]",      #   
84%  #  522%  #  350%  #  421%  # 8375.6/s #
    '35_macro'     => "[% MACRO foo BLOCK %]Hi[% END %][% foo %]",        #   
28%  #  389%  #  263%  #  278%  # 6895.4/s #
    '36_macro_arg' => "[% MACRO foo(n) BLOCK %]Hi[%n%][%END%][%foo(2)%]", #   
17%  #  282%  #  244%  #  190%  # 5934.3/s #
    '37_macro_pro' => "[% MACRO foo PROCESS bar;BLOCK bar%]7[%END;foo%]", #   
38%  #  399%  #  280%  #  323%  # 5772.7/s #
    '38_filter2'   => "[% n = 1 %][% n | repeat(2) %]",                   #   
67%  #  416%  #  332%  #  308%  # 9481.5/s #
    '39_filter'    => "[% n = 1 %][% n FILTER repeat(2) %]",              #   
40%  #  338%  #  277%  #  240%  # 7875.7/s #
    '40_fltr_name' => "[% n=1; n FILTER echo=repeat(2); n FILTER echo%]", #   
-4%  #  302%  #  193%  #  227%  # 5131.5/s #
    '41_constant'  => "[% constants.simple %]",                           #  
116%  #  561%  #  433%  #  417%  # 15104.6/s #
    '42_perl'      => "[%one='ONE'%][% PERL %]print \"[%one%]\"[%END%]",  #   
25%  #  428%  #  267%  #  330%  # 6225.4/s #
    '43_filtervar' => "[% 'hi' | \$filt %]",                              #   
46%  #  498%  #  322%  #  356%  # 9130.4/s #
    '44_filteruri' => "[% ' ' | uri %]",                                  #   
83%  #  597%  #  380%  #  462%  # 11007.6/s #
    '45_filterevl' => "[% foo | eval %]",                                 #  
263%  #  568%  #  455%  #  468%  # 4817.4/s #
    '46_refs'      => "[% b = \\code(1); b(2) %]",                        #   
16%  #  257%  #  207%  #  161%  # 6171.2/s #
    '47_capture'   => "[% foo = BLOCK %]Hi[% END %][% foo %]",            #   
43%  #  410%  #  282%  #  296%  # 9545.1/s #
    '48_complex'   => "$longer_template",                                 #   
-6%  #  273%  #   99%  #  232%  # 1046.3/s #
    # overall                                                             #   
30%  #  409%  #  228%  #  323%  #
};

Reply via email to