Benchmarks to Text::ClearSilver
Text::ClearSilver(CS)のベンチマークをとってみた。
比較はTemplate-Toolkit(TT), HTML::Template::Pro(HT), Text::MicroTemplate(MT)、およびMobaSiF::Template(MST)と行った。
ベンチマークスクリプトは id:tokuhirom のものをベースに少し複雑にした。
結果:
$ perl benchmark/cs_tt_mt_ht.pl 100 # テンプレートの大きさを指定できる 5.10.1 on i686-linux Template: 2.22 Text::MicroTemplate: 0.11 HTML::Template::Pro: 0.94 Text::ClearSilver: 0.10.5.1 MobaSiF::Template: 0.02 Rate TT CS MT HT MST TT 55.1/s -- -99% -99% -100% -100% CS 5023/s 9010% -- -34% -61% -62% MT 7657/s 13787% 52% -- -40% -42% HT 12780/s 23077% 154% 67% -- -3% MST 13128/s 23709% 161% 71% 3% --
結果、HTとMSTはテンプレートが巨大になるほどに際立ってくる。この中で唯一のPure PerlモジュールであるMTはかなり善戦するようだ。CSはTTと比較すると100倍ほど速いものの、MST,HT,MTと比較するとやや劣る。
特性としては、MSTは高速だがモジュールのインターフェイスは最低限のものしかなく、テンプレートの機能も低い。HTはHTMLエスケープをしてからエンジンに渡さなければならないためアトリビュートとしてescape="html"としなければならないため、ミスが生じやすい。MTとCSはモジュールのインターフェイスも充実しており、HTMLエスケープも簡単にできる*1ため使いやすい。
この中では、CSかMTが速度も機能も十分であり安全性も高いため、使いやすいように思う。
#!perl use strict; use warnings; use Text::ClearSilver; use Template; use Text::MicroTemplate 'build_mt'; use HTML::Template::Pro; use Benchmark ':all'; my $cs = Text::ClearSilver->new(VarEscapeMode => 'html'); my $n = shift(@ARGV) || 10; my $tt_tmpl = q{ [% foo %] } x $n; my $mst_tmpl = q{ $= h:foo $ } x $n; my $cs_tmpl = q{ <?cs var:foo ?> } x $n; my $mt_tmpl = q{ <?= $_[0]->{foo} ?> } x $n; my $ht_tmpl = q{ <tmpl_var name="foo"> } x $n; my $mt = build_mt($mt_tmpl); my $ht = HTML::Template::Pro->new( scalarref => \$ht_tmpl, ); my $tt = Template->new(); my $has_mst = eval { require MobaSiF::Template }; my %vars = (foo => 'bar'); printf "%vd %s\n", $^V, $^O; foreach my $mod(qw(Template Text::MicroTemplate HTML::Template::Pro Text::ClearSilver), $has_mst ? 'MobaSiF::Template' : ()) { print $mod, ": ", $mod->VERSION, "\n"; } my $mst_bin = 'mst.bin'; if($has_mst) { MobaSiF::Template::Compiler::compile(\$mst_tmpl, $mst_bin); eval q{ END{ unlink $mst_bin } }; } if(0){ warn _cs(); warn _tt(); warn _mt(); warn _ht(); warn _mst(); exit; } cmpthese( -1, => { 'CS' => \&_cs, 'TT' => \&_tt, 'MT' => \&_mt, 'HT' => \&_ht, $has_mst ? ('MST' => \&_mst) : (), }, ); sub _cs { $cs->process(\$cs_tmpl, \%vars, \my $out ); $out; } sub _tt { $tt->process(\$tt_tmpl, \%vars, \my $out) or die; $out; } sub _mt { $mt->(\%vars); } sub _ht { $ht->param(%vars); my $out = $ht->output(); } sub _mst { MobaSiF::Template::insert($mst_bin, \%vars); } __END__