Template-Toolkit 続き。
Template-Toolkit をいじっていて、なんだか動作がもっさりしているような気がしたのでベンチマークを取ってみる。
ベンチマークスクリプトは
#!/usr/bin/perl use Benchmark; use HTML::Template; use Template; use strict; my $prefix = $ARGV[0]; my %vars = ( test_val => join('', (0..9, "a".."z", "A".."Z")), test_loop => [ { val => 1 }, { val => qq|酒日記 | }, { val => "http://sake-nikki.dyndns.org/cgi-bin/index.cgi?rm=hogehoge" }, ], test_if => (rand > 0.5) ? 1 : 0, ); sub test_tt { my $tt = Template->new({ INCLUDE_PATH => "./", }); my $output; $tt->process($prefix. "test.tt", \%vars, \$output) or die $tt->error; } sub test_tp { my $tp = HTML::Template->new( filename => $prefix. "test.tp", global_vars => 1, die_on_bad_params => 0, ); my $output; $tp->param(%vars); $output = $tp->output; } timethese(100, { 'HTML::Template ' => \&test_tp, 'Template-Toolkit' => \&test_tt, });
こんな感じ。テンプレートは test.tt (Template-Toolkit用) が
test_val=[% test_val %] [% FOREACH l = test_loop %] val=[% l.val %] val_html=[% l.val | html %] [% END %] [% IF test_if %]true[% ELSE %]false[% END %]
で、test.tp (HTML::Template) は、
test_val=<TMPL_VAR name="test_val"> <TMPL_LOOP name="test_loop"> val=<TMPL_VAR name="val"> val_html=<TMPL_VAR name="val" escape="html"> </TMPL_LOOP> <TMPL_IF name="test_if">true<TMPL_ELSE>false</TMPL_IF>
これ。動作としては同等品。更に
- test.tt, test.tp を10個連結した large_test.t[tp]
- test.tt, test.tp を100個連結した huge_test.t[tp]
- test.t[tp] とHTML文書(酒日記を適当に抜粋して 1600 byteほどにしたもの) を、3個づつ連結した real_test.t[tp]
を用意。
...
ベンチマーク結果
test.t[tp] HTML::Template : 0 wallclock secs ( 0.42 usr + 0.01 sys = 0.43 CPU) @ 232.56/s (n=100) Template-Toolkit: 2 wallclock secs ( 1.83 usr + 0.02 sys = 1.85 CPU) @ 54.05/s (n=100) large_test.t[tp] HTML::Template : 4 wallclock secs ( 4.74 usr + 0.01 sys = 4.75 CPU) @ 21.05/s (n=100) Template-Toolkit: 12 wallclock secs (11.85 usr + 0.08 sys = 11.93 CPU) @ 8.38/s (n=100) real_test.t[tp] HTML::Template : 1 wallclock secs ( 1.75 usr + 0.03 sys = 1.78 CPU) @ 56.18/s (n=100) Template-Toolkit: 5 wallclock secs ( 4.40 usr + 0.05 sys = 4.45 CPU) @ 22.47/s (n=100) huge_test.t[tp] HTML::Template : 267 wallclock secs (266.37 usr + 0.08 sys = 266.45 CPU) @ 0.38/s (n=100) Template-Toolkit: 139 wallclock secs (138.85 usr + 0.27 sys = 139.12 CPU) @ 0.72/s (n=100)
huge では Templat-Toolkit が HTML::Template を上まわるものの、それ以外では惨敗。 HTML::Template の圧勝。
両者ともに、一旦コンパイルしたテンプレートをキャッシュすることで高速化ができる (特に mod_perl 環境で有効) ので、キャッシュを有効にして再度ベンチマークを取ってみる。 具体的には、
my $tt = Template->new({ INCLUDE_PATH => "./", + COMPILE_DIR => "/var/tmp/tt/", + COMPILE_EXT => ".ttc", }); my $tp = HTML::Template->new( filename => $prefix. "test.tp", global_vars => 1, die_on_bad_params => 0, + cache => 1, );
としてキャッシュを有効にする。結果は以下。
test.t[tp] HTML::Template : 0 wallclock secs ( 0.24 usr + 0.00 sys = 0.24 CPU) @ 416.67/s (n=100) Template-Toolkit: 0 wallclock secs ( 0.71 usr + 0.02 sys = 0.73 CPU) @ 136.99/s (n=100) large_test.t[tp] HTML::Template : 3 wallclock secs ( 3.67 usr + 0.00 sys = 3.67 CPU) @ 27.25/s (n=100) Template-Toolkit: 3 wallclock secs ( 2.94 usr + 0.03 sys = 2.97 CPU) @ 33.67/s (n=100) real_test.t[tp] HTML::Template : 0 wallclock secs ( 0.65 usr + 0.01 sys = 0.66 CPU) @ 151.52/s (n=100) Template-Toolkit: 2 wallclock secs ( 1.30 usr + 0.02 sys = 1.32 CPU) @ 75.76/s (n=100) huge_test.t[tp] HTML::Template : 274 wallclock secs (274.28 usr + 0.01 sys = 274.29 CPU) @ 0.36/s (n=100) Template-Toolkit: 35 wallclock secs (33.95 usr + 0.24 sys = 34.19 CPU) @ 2.92/s (n=100)
簡単にまとめると、
- 単純な(小さい)テンプレートでは、HTML::Template が速い
- Template-Toolkit は、キャッシュによる速度向上が大きい
- テンプレート上での展開要素が多い場合、Template-Toolkit が有利 (テンプレートが巨大になってもパフォーマンスが落ちにくい)
- 実運用環境では、ほぼ互角
というところでしょうか。HTML::Template のほうがシンプルな分、速度的には有利な感じ。 Template-Toolkit が明らかに高速だった huge_ は、実際の Web アプリケーションではまずありえない (特殊な) テンプレートだし。