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% # };