Text::MicroTemplate と Template-Toolkit のベンチマーク
Perlの軽量フレームワーク(MENTA や NanoA)から生まれた Text::MicroTemplateと、ご存じ Template-Toolkit の比較のため、ベンチマークしてみました。参考までに、こちらも有名どころの HTML::Template も入れてみました。
結果
Benchmark: timing 5000 iterations of HTML::Template, Template-Toolkit, Text::MicroTemplate... HTML::Template: 2 wallclock secs ( 1.68 usr + 0.04 sys = 1.72 CPU) @ 2906.98/s (n=5000) Template-Toolkit: 9 wallclock secs ( 8.73 usr + 0.36 sys = 9.09 CPU) @ 550.06/s (n=5000) Text::MicroTemplate: 10 wallclock secs ( 8.83 usr + 0.44 sys = 9.27 CPU) @ 539.37/s (n=5000) Rate Text::MicroTemplate Template-Toolkit HTML::Template Text::MicroTemplate 539/s -- -2% -81% Template-Toolkit 550/s 2% -- -81% HTML::Template 2907/s 439% 428% --
Mac OS X 10.5、Perl 5.8.8 にて。実際の使用にあわせて、キャッシュ有り、UTF-8フラグを立てる仕様で、単純なテンプレート処理を計っています(コードは下記)。ちなみに、Text::MicroTemplate Ver 0.05、Template-Toolkit Ver 2.21、HTML::Template Ver 2.9 を使用。
HTML::Template は低機能なだけあって速いですね。Text::MicroTemplate と Template-Toolkit は、いずれもPerlで実行できるソースコードを作り出してからそれを eval する仕組みなので、eval のコストがほとんどになってしまうようです。
それじゃあキャッシュさせなかったらどうよ、というベンチマークの結果は以下。キャッシュさせないように、テンプレートの内容を予め読み込んでおいて scalar_ref で渡すようにしています。
Benchmark: timing 5000 iterations of HTML::Template, Template-Toolkit, Text::MicroTemplate... HTML::Template: 5 wallclock secs ( 5.34 usr + 0.01 sys = 5.35 CPU) @ 934.58/s (n=5000) Template-Toolkit: 19 wallclock secs (19.17 usr + 0.05 sys = 19.22 CPU) @ 260.15/s (n=5000) Text::MicroTemplate: 9 wallclock secs ( 9.06 usr + 0.04 sys = 9.10 CPU) @ 549.45/s (n=5000) Rate Template-Toolkit Text::MicroTemplate HTML::Template Template-Toolkit 260/s -- -53% -72% Text::MicroTemplate 549/s 111% -- -41% HTML::Template 935/s 259% 70% --
最近の軽量フレームワーク
私の仕事としては、Perlモジュールが自由にインストールできない、ホスティングだったり管理者がうるさい自社サーバで使うものが多いので、最近の軽量フレームワークやMojoなどはとてもありがたい存在です。ソースコードを読んで自分の業務にあった軽量フレームワークを作ったりして勉強しています。
#Mojo::Template は今回の比較には入れませんでしたが、Text::MicroTemplate はこれをベースにしているので、同じような結果がでるのではないか、と思っています。
PHPでは、同じような理由で CakePHP を使ったりもしています。
こういったニーズって結構あるんじゃないかなぁと思っているのですが、Perlではなかなかメジャーな、PurePerl(コアモジュール含む)なフレームワークって無かったですよね。今回ベンチマークしたモジュールは、全て「.pm」ファイルを置くだけで実行できるPurePerlなテンプレートエンジンです。MENTA や NanoA の作者の方々に感謝しつつ、もっとこの流れが発展することを願っております。
ベンチマークのソース
use strict; use warnings; use utf8; use Encode; use Benchmark qw( timethese cmpthese ); use Text::MicroTemplate::File; use Template; use Template::Provider::Encoding; use Template::Stash::ForceUTF8; use HTML::Template; my $times = shift @ARGV || 1000; my $data = { items => [ { id => 'aaa', name => 'あいうえおかきくけこ', desc => '説明文1です。説明文1です。', stat => 0, }, { id => 'bbb', name => 'さしすせそたちつてと', desc => '説明文2です。説明文2です。', stat => 1, }, { id => 'ccc', name => 'なにぬねのはひふへほ', desc => '説明文3です。説明文3です。', stat => 0, }, ], doc_root => '/path/to/document_root/', }; my $tmpl_tt = './tmpl_tt.html'; my $tmpl_mt = './tmpl_mt.html'; my $tmpl_ht = './tmpl_ht.html'; binmode STDOUT, ':utf8'; my $comp = timethese( $times, { 'Template-Toolkit' => \&template_toolkit, 'Text::MicroTemplate' => \&text_microtemplate, 'HTML::Template' => \&html_template, } ); cmpthese( $comp ); sub template_toolkit { my $tmpl = Template->new( LOAD_TEMPLATES => [ Template::Provider::Encoding->new( RELATIVE => 1, COMPILE_DIR => './cache_tt', ) ], STASH => Template::Stash::ForceUTF8->new(), ); my $html = ''; $tmpl->process( $tmpl_tt, $data, \$html ) or die $tmpl->error(); return $html; } sub text_microtemplate { my $tmpl = Text::MicroTemplate::File->new( cache => 1, ); my $html = $tmpl->render_file( $tmpl_mt, $data ); return ${$html}; } sub html_template { my $tmpl = HTML::Template->new( filename => $tmpl_ht, die_on_bad_params => 0, cache => 1, filter => sub { my $text_ref = shift; ${$text_ref} = Encode::decode( 'utf8', ${$text_ref} ); } ); $tmpl->param( %{$data} ); return $tmpl->output(); }
そうそう、Template-Toolkit の UTF-8 フラグ立てには、Template::Provider::Encodingを使っています。