HTML タグをエスケープする方法 3 通りと速度比較

HTML::Entities を使う方法と、正規表現を段階的に使う方法と、変換テーブルを用意して正規表現で置換する方法と、どれが一番速いか気になったので計測してみました。& から順番に変換していく方法が一番速かったです。ベンチマークスクリプトは以下です。

Rate cpan once step
cpan 372/s -- -32% -56%
once 550/s 48% -- -35%
step 847/s 127% 54% --
use strict;
use warnings;
use Benchmark ':all';
use HTML::Entities;

my $html = join '', <DATA>;
my %table = (
    '&' => '&amp;',
    '<' => '&lt;',
    '>' => '&gt;',
    '"' => '&quot;',
    "'" => '&#39;',
);
my $regex = join '', '([', keys(%table), '])';

cmpthese(timethese(1000, {
    'step' => \&step,
    'once' => \&once,
    'cpan' => \&cpan,
}));

sub step {
    my $str = $html;
    $str =~ s/&/&amp;/go;
    $str =~ s/</&lt;/go;
    $str =~ s/>/&gt;/go;
    $str =~ s/"/&quot;/go;
    $str =~ s/'/&#39;/go;
    $str;
}

sub once {
    my $str = $html;
    $str =~ s/$regex/$table{$1}/go;
    $str;
}

sub cpan {
    my $str = encode_entities($html, q{&<>"'});
    $str;
}

__DATA__
ベンチマーク用の HTML をここに用意
このエントリでは vim で下記ページのソースを使用しました。
:r! GET http://www.perl.org/