#!/usr/bin/perl -w =head1 NAME bench_various_templaters.pl - test the relative performance of several different types of template engines. =cut use strict; use Benchmark qw(timethese cmpthese); use Template; use Template::Stash; use Template::Stash::XS; use Template::Parser::CET; use Text::Template; use Text::Tmpl; use HTML::Template; use HTML::Template::Compiled; use HTML::Template::Expr; use HTML::Template::JIT; use Template::Alloy; use Template::Alloy::XS; use POSIX qw(tmpnam); use File::Path qw(mkpath rmtree); ###----------------------------------------------------------------### my $names = { TA => 'Template::Alloy using TT interface', TA_NOCACHE => 'Template::Alloy with string ref caching off using process_simple', TA_H_NOCACHE => 'Template::Alloy with string ref caching off using HTML::Template interface', TA_P => 'Template::Alloy - Perl code eval based', TA_S => 'Template::Alloy::XS using TT interface using process_simple', TA_X => 'Template::Alloy::XS using TT interface', TA_PS => 'Template::Alloy - Perl code eval based using process_simple', TA_XS => 'Template::Alloy::XS - using process_simple', TA_XP => 'Template::Alloy::XS - Perl code eval based', TA_XPS => 'Template::Alloy::XS - Perl code eval based using process_simple', TA_H => 'Template::Alloy using HTML::Template interface', TA_H_X => 'Template::Alloy::XS using HTML::Template interface', TA_H_XP => 'Template::Alloy::XS using HTML::Template interface - Perl code eval based', TA_XTMPL => 'CGI::Ex::Temmplate::XS using Text::Tmpl interface', HT => 'HTML::Template', HTE => 'HTML::Template::Expr', HTJ => 'HTML::Template::JIT - Compiled to C template', HTC => 'HTML::Template::Compiled', TextTemplate => 'Text::Template - Perl code eval based', TT => 'Template::Toolkit', TTX => 'Template::Toolkit with Stash::XS', TTXCET => 'Template::Toolkit with Stash::XS and Template::Parser::CET', TMPL => 'Text::Tmpl - Engine is C based', RAW => 'Raw perl - no template engine', mem => 'Compiled in memory', file => 'Loaded from file', str => 'From string ref - cached if possible', }; ###----------------------------------------------------------------### ### get cache and compile dirs ready my $dir = tmpnam; my $dir2 = "$dir.cache"; mkpath($dir); mkpath($dir2); END {rmtree $dir; rmtree $dir2}; my @dirs = ($dir); ###----------------------------------------------------------------### my $form = { foo => 'bar', pass_in_something => 'what ever you want', }; my $filler = ((" foo" x 10)."\n") x 10; my $stash_t = { shell_header => "This is a header", shell_footer => "This is a footer", shell_start => "", shell_end => "", a_stuff => [qw(one two three four)], }; my $stash_ht = { shell_header => "This is a header", shell_footer => "This is a footer", shell_start => "", shell_end => "", a_stuff => [map {{name => $_}} qw(one two three four)], }; $FOO::shell_header = $FOO::shell_footer = $FOO::shell_start = $FOO::shell_end = $FOO::a_stuff; $FOO::shell_header = "This is a header"; $FOO::shell_footer = "This is a footer"; $FOO::shell_start = ""; $FOO::shell_end = ""; $FOO::a_stuff = [qw(one two three four)]; ###----------------------------------------------------------------### ### TT style template my $content_tt = <<"DOC"; [% shell_header %] [% shell_start %] $filler [% IF foo %] This is some text. [% END %] [% FOREACH i IN a_stuff %][% i %][% END %] [% pass_in_something %] $filler [% shell_end %] [% shell_footer %] DOC if (open (my $fh, ">$dir/foo.tt")) { print $fh $content_tt; close $fh; } ###----------------------------------------------------------------### ### HTML::Template style my $content_ht = <<"DOC"; $filler This is some text. $filler DOC if (open (my $fh, ">$dir/foo.ht")) { print $fh $content_ht; close $fh; } ###----------------------------------------------------------------### ### Text::Template style template my $content_p = <<"DOC"; {\$shell_header} {\$shell_start} $filler { if (\$foo) { \$OUT .= " This is some text. "; } } { \$OUT .= \$_ foreach \@\$a_stuff; } {\$pass_in_something} $filler {\$shell_end} {\$shell_footer} DOC ###----------------------------------------------------------------### ### Tmpl style template my $content_tmpl = <<"DOC"; $filler This is some text. $filler DOC if (open (my $fh, ">$dir/foo.tmpl")) { print $fh $content_tmpl; close $fh; } ###----------------------------------------------------------------### ### Pure perl base case my $content_raw = sub { my $args = shift; return "$args->{shell_header} $args->{shell_start} $filler ".($args->{foo} ? " This is some text. " : "")." ".(do { my $t = ''; $t .= $_ foreach @{ $args->{a_stuff} }; $t; })." $args->{pass_in_something} $filler $args->{shell_end} $args->{shell_footer} "; }; ###----------------------------------------------------------------### ### The TT interface allows for a single object to be cached and reused. my %Alloy_DOCUMENTS; my %AlloyX_DOCUMENTS; my %AlloyXP_DOCUMENTS; my $tt = Template->new( INCLUDE_PATH => \@dirs, STASH => Template::Stash->new($stash_t)); my $ttx = Template->new( INCLUDE_PATH => \@dirs, STASH => Template::Stash::XS->new($stash_t)); my $ta = Template::Alloy->new( INCLUDE_PATH => \@dirs, VARIABLES => $stash_t); my $tap = Template::Alloy->new( INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_PERL => 1); my $taps = Template::Alloy->new( INCLUDE_PATH => \@dirs, COMPILE_PERL => 1); my $tax = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t); my $taxs = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t); my $taxp = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_PERL => 1); my $taxps = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, COMPILE_PERL => 1); ###----------------------------------------------------------------### my $tests = { ###----------------------------------------------------------------### ### str infers that we are pulling from a string reference TextTemplate_str => sub { my $pt = Text::Template->new( TYPE => 'STRING', SOURCE => $content_p, HASH => $form); my $out = $pt->fill_in(PACKAGE => 'FOO', HASH => $form); }, TT_str => sub { my $t = Template->new(STASH => Template::Stash->new($stash_t)); my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TTX_str => sub { my $t = Template->new(STASH => Template::Stash::XS->new($stash_t)); my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TTXCET_str => sub { my $t = Template->new(STASH => Template::Stash::XS->new($stash_t), PARSER => Template::Parser::CET->new); my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TA_str => sub { my $t = Template::Alloy->new(VARIABLES => $stash_t); $t->{'_documents'} = \%Alloy_DOCUMENTS; my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TA_NOCACHE_str => sub { my $t = Template::Alloy->new(CACHE_STR_REFS => 0); my $out = ""; $t->process_simple(\$content_tt, {%$stash_t, %$form}, \$out); $out; }, TA_X_str => sub { my $t = Template::Alloy::XS->new(VARIABLES => $stash_t); $t->{'_documents'} = \%AlloyX_DOCUMENTS; my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TA_XP_str => sub { my $t = Template::Alloy::XS->new(VARIABLES => $stash_t, COMPILE_PERL => 1); $t->{'_documents'} = \%AlloyXP_DOCUMENTS; my $out = ""; $t->process(\$content_tt, $form, \$out); $out; }, TA_XPS_str => sub { my $t = Template::Alloy::XS->new(COMPILE_PERL => 1); $t->{'_documents'} = \%AlloyXP_DOCUMENTS; my $out = ""; $t->process_simple(\$content_tt, {%$stash_t, %$form}, \$out); $out; }, TA_H_str => sub { my $t = Template::Alloy->new( type => 'scalarref', source => \$content_ht, case_sensitve=>1, cache => 1); $t->{'_documents'} = \%Alloy_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_NOCACHE_str => sub { my $t = Template::Alloy->new( type => 'scalarref', source => \$content_ht, case_sensitve=>1, CACHE_STR_REFS => 1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_X_str => sub { my $t = Template::Alloy::XS->new(type => 'scalarref', source => \$content_ht, case_sensitve=>1, cache => 1); $t->{'_documents'} = \%AlloyX_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_XP_str => sub { my $t = Template::Alloy::XS->new(type => 'scalarref', source => \$content_ht, case_sensitve=>1, COMPILE_PERL => 1, cache => 1); $t->{'_documents'} = \%AlloyXP_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HT_str => sub { my $t = HTML::Template->new( type => 'scalarref', source => \$content_ht, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTE_str => sub { my $t = HTML::Template::Expr->new( type => 'scalarref', source => \$content_ht, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTC_str => sub { my $t = HTML::Template::Compiled->new(type => 'scalarref', source => \$content_ht, case_sensitve=>1, cache => 1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TMPL_str => sub { my $t = Text::Tmpl->new; for my $ref (@{ $stash_ht->{'a_stuff'} }) { $t->loop_iteration('a_stuff')->set_values($ref); } $t->set_values($stash_ht); $t->set_values($form); $t->set_delimiters(''); $t->set_dir("$dir/"); $t->set_strip(0); my $out = $t->parse_string($content_tmpl); }, ###----------------------------------------------------------------### ### compile means item was compiled to optree or perlcode and stored on disk ### this should try to load the template from disk each time TT_file => sub { my $tt = Template->new(INCLUDE_PATH => \@dirs, STASH => Template::Stash->new($stash_t), COMPILE_DIR => $dir2); my $out = ""; $tt->process('foo.tt', $form, \$out); $out; }, TTX_file => sub { my $tt = Template->new(INCLUDE_PATH => \@dirs, STASH => Template::Stash::XS->new($stash_t), COMPILE_DIR => $dir2); my $out = ""; $tt->process('foo.tt', $form, \$out); $out; }, TA_file => sub { my $t = Template::Alloy->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_DIR => $dir2); my $out = ''; $t->process('foo.tt', $form, \$out); $out; }, TA_P_file => sub { my $t = Template::Alloy->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_DIR => $dir2, COMPILE_PERL => 1); my $out = ''; $t->process('foo.tt', $form, \$out); $out; }, TA_S_file => sub { my $t = Template::Alloy->new(INCLUDE_PATH => \@dirs, COMPILE_DIR => $dir2); my $out = ''; $t->process_simple('foo.tt', {%$stash_t, %$form}, \$out); $out; }, TA_X_file => sub { my $t = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_DIR => $dir2); my $out = ''; $t->process('foo.tt', $form, \$out); $out; }, TA_XS_file => sub { my $t = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, COMPILE_DIR => $dir2); my $out = ''; $t->process_simple('foo.tt', {%$stash_t, %$form}, \$out); $out; }, TA_XP_file => sub { my $t = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, VARIABLES => $stash_t, COMPILE_DIR => $dir2, COMPILE_PERL => 1); my $out = ''; $t->process('foo.tt', $form, \$out); $out; }, TA_XPS_file => sub { my $t = Template::Alloy::XS->new(INCLUDE_PATH => \@dirs, COMPILE_DIR => $dir2, COMPILE_PERL => 1); my $out = ""; $t->process_simple(\$content_tt, {%$stash_t, %$form}, \$out); $out; }, TA_H_file => sub { my $t = Template::Alloy->new(type => 'filename', source => "foo.ht", file_cache => 1, path => \@dirs, file_cache_dir => $dir2, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_X_file => sub { my $t = Template::Alloy::XS->new(type => 'filename', source => "foo.ht", file_cache => 1, path => \@dirs, file_cache_dir => $dir2, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_XP_file => sub { my $t = Template::Alloy::XS->new(type => 'filename', source => "foo.ht", file_cache => 1, path => \@dirs, file_cache_dir => $dir2, case_sensitve=>1, compile_perl => 1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HT_file => sub { my $t = HTML::Template->new(type => 'filename', source => "foo.ht", file_cache => 1, path => \@dirs, file_cache_dir => $dir2, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTC_file => sub { my $t = HTML::Template::Compiled->new(type => 'filename', source => "foo.ht", file_cache => 1, path => \@dirs, file_cache_dir => $dir2, case_sensitve=>1, cache => 0); $t->param($stash_ht); $t->param($form); my $out = $t->output; # $t->clear_cache; # caches in memory by default - can't disable it # return $out; }, TMPL_file => sub { my $t = Text::Tmpl->new; for my $ref (@{ $stash_ht->{'a_stuff'} }) { $t->loop_iteration('a_stuff')->set_values($ref); } $t->set_values($stash_ht); $t->set_values($form); $t->set_delimiters(''); $t->set_dir("$dir/"); $t->set_strip(0); my $out = $t->parse_file("foo.tmpl"); }, TA_XTMPL_file => sub { my $t = Template::Alloy::XS->new; for my $ref (@{ $stash_ht->{'a_stuff'} }) { $t->loop_iteration('a_stuff')->set_values($ref); } $t->set_values($stash_ht); $t->set_values($form); $t->set_delimiters(''); $t->set_dir("$dir/"); $t->set_strip(0); my $out = $t->parse_file("foo.tmpl"); }, ###----------------------------------------------------------------### ### mem indicates that the compiled form is stored in memory TT_mem => sub { my $out = ""; $tt->process( 'foo.tt', $form, \$out); $out }, TTX_mem => sub { my $out = ""; $ttx->process( 'foo.tt', $form, \$out); $out }, TA_mem => sub { my $out = ""; $ta->process( 'foo.tt', $form, \$out); $out }, TA_PS_mem => sub { my $out = ""; $taps->process_simple( 'foo.tt', {%$stash_t, %$form}, \$out); $out }, TA_X_mem => sub { my $out = ""; $tax->process( 'foo.tt', $form, \$out); $out }, TA_XP_mem => sub { my $out = ""; $taxp->process('foo.tt', $form, \$out); $out }, TA_XPS_mem => sub { my $out = ""; $taxps->process_simple('foo.tt', {%$stash_t, %$form}, \$out); $out }, TA_P_mem => sub { my $out = ""; $tap->process( 'foo.tt', $form, \$out); $out }, TA_H_mem => sub { my $t = Template::Alloy->new( filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1); $t->{'_documents'} = \%Alloy_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_X_mem => sub { my $t = Template::Alloy::XS->new(filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1); $t->{'_documents'} = \%AlloyX_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, TA_H_XP_mem => sub { my $t = Template::Alloy::XS->new(filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1, compile_perl => 1, cache => 1); $t->{'_documents'} = \%AlloyXP_DOCUMENTS; $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HT_mem => sub { my $t = HTML::Template->new( filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTC_mem => sub { my $t = HTML::Template::Compiled->new( filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTE_mem => sub { my $t = HTML::Template::Expr->new( filename => "foo.ht", path => \@dirs, cache => 1, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, HTJ_mem => sub { # this is interesting - it is compiled - but it is pulled into memory just once my $t = HTML::Template::JIT->new( filename => "foo.ht", path => \@dirs, jit_path => $dir2, case_sensitve=>1); $t->param($stash_ht); $t->param($form); my $out = $t->output; }, #RAW_mem => sub { # my $out = $content_raw->({%$stash_t, %$form}); #}, }; my $test = $tests->{'TT_str'}->(); foreach my $name (sort keys %$tests) { if ($test ne $tests->{$name}->()) { print "--------------------------TT_str-------\n"; print $test; print "--------------------------$name--------\n"; print $tests->{$name}->(); die "$name did not match TT_str output\n"; } $name =~ /(\w+)_(\w+)/; print "$name - $names->{$1} - ($names->{$2})\n"; } ###----------------------------------------------------------------### ### and now - the tests - grouped by common capability my %mem_tests = map {my $k=$_; $k=~s/_mem$//; $k => $tests->{$_}} grep {/_mem$/} keys %$tests; my %cpl_tests = map {my $k=$_; $k=~s/_file$//; $k => $tests->{$_}} grep {/_file$/} keys %$tests; my %str_tests = map {my $k=$_; $k=~s/_str$//; $k => $tests->{$_}} grep {/_str$/} keys %$tests; print "---Match Run Through----------------------------------------------------\n"; my $match; # run through once to make sure they are working foreach my $key (sort keys %$tests) { my $out = $tests->{$key}->(); if ($match) { die "$key didn't match" if $out ne $match } else { $match = $out } } print " All test output matched!\n"; print "---STR------------------------------------------------------------------\n"; print "From a string or scalarref tests\n"; cmpthese timethese (-2, \%str_tests); print "---FILE-----------------------------------------------------------------\n"; print "Compiled and cached on the file system tests\n"; cmpthese timethese (-2, \%cpl_tests); print "---MEM------------------------------------------------------------------\n"; print "Cached in memory tests\n"; cmpthese timethese (-2, \%mem_tests); #print "------------------------------------------------------------------------\n"; #print "All variants together\n"; #cmpthese timethese (-2, $tests); ###----------------------------------------------------------------### __END__ =head1 VERSIONS Template::Alloy 1.009 Template 2.19 Template::Parser::CET 0.05 Text::Tmpl 0.30 Text::Template 1.44 HTML::Template 2.9 HTML::Template::Expr 0.07 HTML::Template::JIT 0.05 HTML::Template::Compiled 0.89 =head1 SAMPLE OUTPUT HTC_file - HTML::Template::Compiled - (Loaded from file) HTC_mem - HTML::Template::Compiled - (Compiled in memory) HTC_str - HTML::Template::Compiled - (From string ref - cached if possible) HTE_mem - HTML::Template::Expr - (Compiled in memory) HTE_str - HTML::Template::Expr - (From string ref - cached if possible) HTJ_mem - HTML::Template::JIT - Compiled to C template - (Compiled in memory) HT_file - HTML::Template - (Loaded from file) HT_mem - HTML::Template - (Compiled in memory) HT_str - HTML::Template - (From string ref - cached if possible) TA_H_NOCACHE_str - Template::Alloy with string ref caching off using HTML::Template interface - (From string ref - cached if possible) TA_H_XP_file - Template::Alloy::XS using HTML::Template interface - Perl code eval based - (Loaded from file) TA_H_XP_mem - Template::Alloy::XS using HTML::Template interface - Perl code eval based - (Compiled in memory) TA_H_XP_str - Template::Alloy::XS using HTML::Template interface - Perl code eval based - (From string ref - cached if possible) TA_H_X_file - Template::Alloy::XS using HTML::Template interface - (Loaded from file) TA_H_X_mem - Template::Alloy::XS using HTML::Template interface - (Compiled in memory) TA_H_X_str - Template::Alloy::XS using HTML::Template interface - (From string ref - cached if possible) TA_H_file - Template::Alloy using HTML::Template interface - (Loaded from file) TA_H_mem - Template::Alloy using HTML::Template interface - (Compiled in memory) TA_H_str - Template::Alloy using HTML::Template interface - (From string ref - cached if possible) TA_NOCACHE_str - Template::Alloy with string ref caching off using process_simple - (From string ref - cached if possible) TA_PS_mem - Template::Alloy - Perl code eval based using process_simple - (Compiled in memory) TA_P_file - Template::Alloy - Perl code eval based - (Loaded from file) TA_P_mem - Template::Alloy - Perl code eval based - (Compiled in memory) TA_S_file - Template::Alloy::XS using TT interface using process_simple - (Loaded from file) TA_XPS_file - Template::Alloy::XS - Perl code eval based using process_simple - (Loaded from file) TA_XPS_mem - Template::Alloy::XS - Perl code eval based using process_simple - (Compiled in memory) TA_XPS_str - Template::Alloy::XS - Perl code eval based using process_simple - (From string ref - cached if possible) TA_XP_file - Template::Alloy::XS - Perl code eval based - (Loaded from file) TA_XP_mem - Template::Alloy::XS - Perl code eval based - (Compiled in memory) TA_XP_str - Template::Alloy::XS - Perl code eval based - (From string ref - cached if possible) TA_XS_file - Template::Alloy::XS - using process_simple - (Loaded from file) TA_XTMPL_file - CGI::Ex::Temmplate::XS using Text::Tmpl interface - (Loaded from file) TA_X_file - Template::Alloy::XS using TT interface - (Loaded from file) TA_X_mem - Template::Alloy::XS using TT interface - (Compiled in memory) TA_X_str - Template::Alloy::XS using TT interface - (From string ref - cached if possible) TA_file - Template::Alloy using TT interface - (Loaded from file) TA_mem - Template::Alloy using TT interface - (Compiled in memory) TA_str - Template::Alloy using TT interface - (From string ref - cached if possible) TMPL_file - Text::Tmpl - Engine is C based - (Loaded from file) TMPL_str - Text::Tmpl - Engine is C based - (From string ref - cached if possible) TTXCET_str - Template::Toolkit with Stash::XS and Template::Parser::CET - (From string ref - cached if possible) TTX_file - Template::Toolkit with Stash::XS - (Loaded from file) TTX_mem - Template::Toolkit with Stash::XS - (Compiled in memory) TTX_str - Template::Toolkit with Stash::XS - (From string ref - cached if possible) TT_file - Template::Toolkit - (Loaded from file) TT_mem - Template::Toolkit - (Compiled in memory) TT_str - Template::Toolkit - (From string ref - cached if possible) TextTemplate_str - Text::Template - Perl code eval based - (From string ref - cached if possible) ---Match Run Through---------------------------------------------------- All test output matched! ---STR------------------------------------------------------------------ From a string or scalarref tests Benchmark: running HT, HTC, HTE, TA, TA_H, TA_H_NOCACHE, TA_H_X, TA_H_XP, TA_NOCACHE, TA_X, TA_XP, TA_XPS, TMPL, TT, TTX, TTXCET, TextTemplate for at least 2 CPU seconds... HT: 2 wallclock secs ( 2.08 usr + 0.00 sys = 2.08 CPU) @ 1230.29/s (n=2559) HTC: 2 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 210.53/s (n=440) HTE: 3 wallclock secs ( 2.17 usr + 0.00 sys = 2.17 CPU) @ 884.79/s (n=1920) TA: 3 wallclock secs ( 2.12 usr + 0.00 sys = 2.12 CPU) @ 3617.92/s (n=7670) TA_H: 3 wallclock secs ( 2.17 usr + 0.01 sys = 2.18 CPU) @ 3793.58/s (n=8270) TA_H_NOCACHE: 2 wallclock secs ( 2.02 usr + 0.01 sys = 2.03 CPU) @ 1400.99/s (n=2844) TA_H_X: 2 wallclock secs ( 2.15 usr + 0.00 sys = 2.15 CPU) @ 5321.40/s (n=11441) TA_H_XP: 2 wallclock secs ( 2.19 usr + 0.00 sys = 2.19 CPU) @ 5293.15/s (n=11592) TA_NOCACHE: 2 wallclock secs ( 2.00 usr + 0.01 sys = 2.01 CPU) @ 1292.04/s (n=2597) TA_X: 2 wallclock secs ( 2.06 usr + 0.01 sys = 2.07 CPU) @ 5607.73/s (n=11608) TA_XP: 2 wallclock secs ( 2.16 usr + 0.00 sys = 2.16 CPU) @ 7106.48/s (n=15350) TA_XPS: 2 wallclock secs ( 2.12 usr + 0.00 sys = 2.12 CPU) @ 8063.68/s (n=17095) TMPL: 2 wallclock secs ( 2.02 usr + 0.02 sys = 2.04 CPU) @ 8107.35/s (n=16539) TT: 2 wallclock secs ( 2.14 usr + 0.01 sys = 2.15 CPU) @ 312.09/s (n=671) TTX: 2 wallclock secs ( 2.16 usr + 0.01 sys = 2.17 CPU) @ 326.27/s (n=708) TTXCET: 2 wallclock secs ( 2.16 usr + 0.01 sys = 2.17 CPU) @ 516.13/s (n=1120) TextTemplate: 2 wallclock secs ( 1.99 usr + 0.01 sys = 2.00 CPU) @ 1197.50/s (n=2395) Rate HTC TT TTX TTXCET HTE TextTemplate HT TA_NOCACHE TA_H_NOCACHE TA TA_H TA_H_XP TA_H_X TA_X TA_XP TA_XPS TMPL HTC 211/s -- -33% -35% -59% -76% -82% -83% -84% -85% -94% -94% -96% -96% -96% -97% -97% -97% TT 312/s 48% -- -4% -40% -65% -74% -75% -76% -78% -91% -92% -94% -94% -94% -96% -96% -96% TTX 326/s 55% 5% -- -37% -63% -73% -73% -75% -77% -91% -91% -94% -94% -94% -95% -96% -96% TTXCET 516/s 145% 65% 58% -- -42% -57% -58% -60% -63% -86% -86% -90% -90% -91% -93% -94% -94% HTE 885/s 320% 184% 171% 71% -- -26% -28% -32% -37% -76% -77% -83% -83% -84% -88% -89% -89% TextTemplate 1197/s 469% 284% 267% 132% 35% -- -3% -7% -15% -67% -68% -77% -77% -79% -83% -85% -85% HT 1230/s 484% 294% 277% 138% 39% 3% -- -5% -12% -66% -68% -77% -77% -78% -83% -85% -85% TA_NOCACHE 1292/s 514% 314% 296% 150% 46% 8% 5% -- -8% -64% -66% -76% -76% -77% -82% -84% -84% TA_H_NOCACHE 1401/s 565% 349% 329% 171% 58% 17% 14% 8% -- -61% -63% -74% -74% -75% -80% -83% -83% TA 3618/s 1619% 1059% 1009% 601% 309% 202% 194% 180% 158% -- -5% -32% -32% -35% -49% -55% -55% TA_H 3794/s 1702% 1116% 1063% 635% 329% 217% 208% 194% 171% 5% -- -28% -29% -32% -47% -53% -53% TA_H_XP 5293/s 2414% 1596% 1522% 926% 498% 342% 330% 310% 278% 46% 40% -- -1% -6% -26% -34% -35% TA_H_X 5321/s 2428% 1605% 1531% 931% 501% 344% 333% 312% 280% 47% 40% 1% -- -5% -25% -34% -34% TA_X 5608/s 2564% 1697% 1619% 986% 534% 368% 356% 334% 300% 55% 48% 6% 5% -- -21% -30% -31% TA_XP 7106/s 3276% 2177% 2078% 1277% 703% 493% 478% 450% 407% 96% 87% 34% 34% 27% -- -12% -12% TA_XPS 8064/s 3730% 2484% 2371% 1462% 811% 573% 555% 524% 476% 123% 113% 52% 52% 44% 13% -- -1% TMPL 8107/s 3751% 2498% 2385% 1471% 816% 577% 559% 527% 479% 124% 114% 53% 52% 45% 14% 1% -- ---FILE----------------------------------------------------------------- Compiled and cached on the file system tests Benchmark: running HT, HTC, TA, TA_H, TA_H_X, TA_H_XP, TA_P, TA_S, TA_X, TA_XP, TA_XPS, TA_XS, TA_XTMPL, TMPL, TT, TTX for at least 2 CPU seconds... HT: 3 wallclock secs ( 2.10 usr + 0.05 sys = 2.15 CPU) @ 1902.33/s (n=4090) HTC: 2 wallclock secs ( 2.18 usr + 0.02 sys = 2.20 CPU) @ 867.73/s (n=1909) TA: 2 wallclock secs ( 2.10 usr + 0.08 sys = 2.18 CPU) @ 2462.84/s (n=5369) TA_H: 3 wallclock secs ( 2.03 usr + 0.06 sys = 2.09 CPU) @ 2345.93/s (n=4903) TA_H_X: 3 wallclock secs ( 2.09 usr + 0.06 sys = 2.15 CPU) @ 2937.67/s (n=6316) TA_H_XP: 2 wallclock secs ( 2.03 usr + 0.05 sys = 2.08 CPU) @ 1229.81/s (n=2558) TA_P: 2 wallclock secs ( 2.15 usr + 0.04 sys = 2.19 CPU) @ 1302.74/s (n=2853) TA_S: 2 wallclock secs ( 1.92 usr + 0.10 sys = 2.02 CPU) @ 2575.74/s (n=5203) TA_X: 2 wallclock secs ( 2.04 usr + 0.11 sys = 2.15 CPU) @ 3330.23/s (n=7160) TA_XP: 2 wallclock secs ( 2.04 usr + 0.06 sys = 2.10 CPU) @ 1522.38/s (n=3197) TA_XPS: 2 wallclock secs ( 2.05 usr + 0.05 sys = 2.10 CPU) @ 1556.19/s (n=3268) TA_XS: 2 wallclock secs ( 2.06 usr + 0.11 sys = 2.17 CPU) @ 3534.10/s (n=7669) TA_XTMPL: 2 wallclock secs ( 2.11 usr + 0.02 sys = 2.13 CPU) @ 1201.41/s (n=2559) TMPL: 2 wallclock secs ( 1.90 usr + 0.20 sys = 2.10 CPU) @ 6977.14/s (n=14652) TT: 2 wallclock secs ( 2.09 usr + 0.03 sys = 2.12 CPU) @ 756.13/s (n=1603) TTX: 2 wallclock secs ( 2.14 usr + 0.03 sys = 2.17 CPU) @ 824.88/s (n=1790) Rate TT TTX HTC TA_XTMPL TA_H_XP TA_P TA_XP TA_XPS HT TA_H TA TA_S TA_H_X TA_X TA_XS TMPL TT 756/s -- -8% -13% -37% -39% -42% -50% -51% -60% -68% -69% -71% -74% -77% -79% -89% TTX 825/s 9% -- -5% -31% -33% -37% -46% -47% -57% -65% -67% -68% -72% -75% -77% -88% HTC 868/s 15% 5% -- -28% -29% -33% -43% -44% -54% -63% -65% -66% -70% -74% -75% -88% TA_XTMPL 1201/s 59% 46% 38% -- -2% -8% -21% -23% -37% -49% -51% -53% -59% -64% -66% -83% TA_H_XP 1230/s 63% 49% 42% 2% -- -6% -19% -21% -35% -48% -50% -52% -58% -63% -65% -82% TA_P 1303/s 72% 58% 50% 8% 6% -- -14% -16% -32% -44% -47% -49% -56% -61% -63% -81% TA_XP 1522/s 101% 85% 75% 27% 24% 17% -- -2% -20% -35% -38% -41% -48% -54% -57% -78% TA_XPS 1556/s 106% 89% 79% 30% 27% 19% 2% -- -18% -34% -37% -40% -47% -53% -56% -78% HT 1902/s 152% 131% 119% 58% 55% 46% 25% 22% -- -19% -23% -26% -35% -43% -46% -73% TA_H 2346/s 210% 184% 170% 95% 91% 80% 54% 51% 23% -- -5% -9% -20% -30% -34% -66% TA 2463/s 226% 199% 184% 105% 100% 89% 62% 58% 29% 5% -- -4% -16% -26% -30% -65% TA_S 2576/s 241% 212% 197% 114% 109% 98% 69% 66% 35% 10% 5% -- -12% -23% -27% -63% TA_H_X 2938/s 289% 256% 239% 145% 139% 125% 93% 89% 54% 25% 19% 14% -- -12% -17% -58% TA_X 3330/s 340% 304% 284% 177% 171% 156% 119% 114% 75% 42% 35% 29% 13% -- -6% -52% TA_XS 3534/s 367% 328% 307% 194% 187% 171% 132% 127% 86% 51% 43% 37% 20% 6% -- -49% TMPL 6977/s 823% 746% 704% 481% 467% 436% 358% 348% 267% 197% 183% 171% 138% 110% 97% -- ---MEM------------------------------------------------------------------ Cached in memory tests Benchmark: running HT, HTC, HTE, HTJ, TA, TA_H, TA_H_X, TA_H_XP, TA_P, TA_PS, TA_X, TA_XP, TA_XPS, TT, TTX for at least 2 CPU seconds... HT: 2 wallclock secs ( 2.10 usr + 0.04 sys = 2.14 CPU) @ 2670.56/s (n=5715) HTC: 3 wallclock secs ( 2.00 usr + 0.05 sys = 2.05 CPU) @ 8212.68/s (n=16836) HTE: 2 wallclock secs ( 2.16 usr + 0.01 sys = 2.17 CPU) @ 1543.78/s (n=3350) HTJ: 2 wallclock secs ( 1.99 usr + 0.08 sys = 2.07 CPU) @ 6197.58/s (n=12829) TA: 2 wallclock secs ( 2.08 usr + 0.03 sys = 2.11 CPU) @ 3872.51/s (n=8171) TA_H: 2 wallclock secs ( 2.11 usr + 0.02 sys = 2.13 CPU) @ 3882.63/s (n=8270) TA_H_X: 2 wallclock secs ( 2.07 usr + 0.05 sys = 2.12 CPU) @ 5396.70/s (n=11441) TA_H_XP: 2 wallclock secs ( 2.15 usr + 0.03 sys = 2.18 CPU) @ 5248.17/s (n=11441) TA_P: 2 wallclock secs ( 2.11 usr + 0.03 sys = 2.14 CPU) @ 4565.42/s (n=9770) TA_PS: 2 wallclock secs ( 2.08 usr + 0.04 sys = 2.12 CPU) @ 4829.72/s (n=10239) TA_X: 2 wallclock secs ( 2.07 usr + 0.02 sys = 2.09 CPU) @ 6225.36/s (n=13011) TA_XP: 2 wallclock secs ( 2.06 usr + 0.06 sys = 2.12 CPU) @ 8068.40/s (n=17105) TA_XPS: 2 wallclock secs ( 2.09 usr + 0.07 sys = 2.16 CPU) @ 9045.83/s (n=19539) TT: 2 wallclock secs ( 2.22 usr + 0.01 sys = 2.23 CPU) @ 2297.31/s (n=5123) TTX: 2 wallclock secs ( 2.10 usr + 0.02 sys = 2.12 CPU) @ 3377.36/s (n=7160) Rate HTE TT HT TTX TA TA_H TA_P TA_PS TA_H_XP TA_H_X HTJ TA_X TA_XP HTC TA_XPS HTE 1544/s -- -33% -42% -54% -60% -60% -66% -68% -71% -71% -75% -75% -81% -81% -83% TT 2297/s 49% -- -14% -32% -41% -41% -50% -52% -56% -57% -63% -63% -72% -72% -75% HT 2671/s 73% 16% -- -21% -31% -31% -42% -45% -49% -51% -57% -57% -67% -67% -70% TTX 3377/s 119% 47% 26% -- -13% -13% -26% -30% -36% -37% -46% -46% -58% -59% -63% TA 3873/s 151% 69% 45% 15% -- -0% -15% -20% -26% -28% -38% -38% -52% -53% -57% TA_H 3883/s 152% 69% 45% 15% 0% -- -15% -20% -26% -28% -37% -38% -52% -53% -57% TA_P 4565/s 196% 99% 71% 35% 18% 18% -- -5% -13% -15% -26% -27% -43% -44% -50% TA_PS 4830/s 213% 110% 81% 43% 25% 24% 6% -- -8% -11% -22% -22% -40% -41% -47% TA_H_XP 5248/s 240% 128% 97% 55% 36% 35% 15% 9% -- -3% -15% -16% -35% -36% -42% TA_H_X 5397/s 250% 135% 102% 60% 39% 39% 18% 12% 3% -- -13% -13% -33% -34% -40% HTJ 6198/s 301% 170% 132% 84% 60% 60% 36% 28% 18% 15% -- -0% -23% -25% -31% TA_X 6225/s 303% 171% 133% 84% 61% 60% 36% 29% 19% 15% 0% -- -23% -24% -31% TA_XP 8068/s 423% 251% 202% 139% 108% 108% 77% 67% 54% 50% 30% 30% -- -2% -11% HTC 8213/s 432% 257% 208% 143% 112% 112% 80% 70% 56% 52% 33% 32% 2% -- -9% TA_XPS 9046/s 486% 294% 239% 168% 134% 133% 98% 87% 72% 68% 46% 45% 12% 10% -- =cut