How slow "HTML escape" is?
そういえばXslateのHTMLエスケープってどのくらい遅いのだろか、と思い、変数展開のベンチマークに「HTMLエスケープなし」を加えて測ってみたところ、驚くべき結果になった。
以下の"xslate"が<: $value :>で、"xslate/raw"が<: $value | raw :>の速度の比較である。
$ perl benchmark/interpolate.pl Perl/5.10.1 i686-linux Text::Xslate/0.1053 Text::MicroTemplate/0.13 1..4 ok 1 - xslate/raw (w/o escaping) ok 2 - Text::MicroTemplate ok 3 - s///g ok 4 - sprintf Rate s///g TMT xslate/raw xslate sprintf s///g 6400/s -- -6% -58% -85% -85% TMT 6826/s 7% -- -55% -84% -85% xslate/raw 15175/s 137% 122% -- -64% -66% xslate 41918/s 555% 514% 176% -- -5% sprintf 44111/s 589% 546% 191% 5% --
なんと、rawフィルタをつけると圧倒的に遅くなってしまう!rawフィルタは最適化によって取り除かれるので、その分のオーバーヘッドはないはずだ。これは、最適化されたHTMLエスケープルーチンよりPerl_sv_catsv()の方が遅いのだろう。
これはいくらなんでもあまりにひどいので、raw文字列の出力を最適化したところ、以下のようになった。
Rate s///g TMT sprintf xslate xslate/raw s///g 6400/s -- -6% -88% -90% -91% TMT 6826/s 7% -- -87% -90% -90% sprintf 52609/s 722% 671% -- -20% -25% xslate 66166/s 934% 869% 26% -- -5% xslate/raw 69818/s 991% 923% 33% 6% --
目論見通り、rawフィルタをかけた方がわずかに高速になった。しかし、その差は僅かである*1。
脱線したがとにかく、十分に最適化すれば、HTMLエスケープ処理によるオーバーヘッドは無視していいくらい小さくなるようだ。無駄なオーバーヘッドがかかることを心配してrawフィルタやescape => "none"オプションを使う必要はまったくない。