CGI::Ex::Fillなんてのがあったのか

昨日の記事の続き

2008年02月16日 tomyhero tomyhero CGI::Ex::Fill のべんちとか性能はどうなのかと思った

id:tomyheroさんからの情報でCGI::Ex::Fillっていう、Liteと同じく正規表現ベースでFillInFormしてくれるものが既に存在していたのを知った。

ってことでCGI::Ex::Fillも交えて再度ベンチをとってみた。

コードは以下

use Benchmark qw(cmpthese timethese :hireswallclock);

use CGI::Ex::Fill ();
use HTML::FillInForm;
use HTML::FillInForm::Lite;

my $str = q{
    <form>
    <input type="text" name="text_data1" value="" >
    <input type="text" name="text_data2" value="" >
    <input type="text" name="text_data3" value="" >
    <input type="text" name="text_data4" value="" >
    <input type="text" name="text_data5" value="" >
    <input type="password" name="pass_data1" value="" >
    <input type="password" name="pass_data2" value="" >
    <select name="select_data">
        <option value="1">a</option>
        <option value="2">b</option>
        <option value="3">c</option>
        <option value="4">d</option>
        <option value="5">e</option>
    </select>
    <input type="radio" name="radio_data" value="0">a
    <input type="radio" name="radio_data" value="1">b
    <input type="radio" name="radio_data" value="2">c
    <input type="radio" name="radio_data" value="3">d
    <input type="radio" name="radio_data" value="4">e
    <input type="radio" name="radio_data" value="5">f
    <textarea name="textarea_data">
    </textarea>
    <input type="submit">
    </form>
};

my $fdat = {
    text_data1 => 'foo',
    text_data2 => 'bar',
    text_pass1 => 'pas',
    select_data => '1',
    radio_data => '0',
    textarea_data => 'BBBBBB',
};

sub fill_cgi {
    my $output = $str;
    CGI::Ex::Fill::fill({ text => \$output, form => $fdat });
}

sub fill_lite {
    my $output = HTML::FillInForm::Lite->new->fill(
        \$str,$fdat
    );
}

sub fill {
    my $output = HTML::FillInForm->new->fill(
        scalarref => \$str,
        fdat      => $fdat,
    );
}

cmpthese(1000,{
    'fill'      => \&fill,
    'fill_cgi'  => \&fill_cgi,
    'fill_lite' => \&fill_lite,
});

__END__

            Rate  fill_cgi      fill fill_lite
fill_cgi   552/s        --      -29%      -48%
fill       780/s       41%        --      -27%
fill_lite 1067/s       93%       37%        --

HTML::FillInFormよりもさらに遅いという結果に。

CGIの方使うくらいならLiteの方使う方が遥かにマシってことか。

ただLiteはLiteで、id:tokuhiromさんが「::Lite は必要な処理をスッとばしてる部分もあるんじゃないかね」と指摘してたけど、確かにそういう面もあるかもしれないので導入するにしても慎重にしないといけないかもしれないですね。

既に分かってる範囲でHTML::FillInFormとLiteの違いを以下に列挙しときます。

  • optionは閉じタグ付いてないとselected突っ込んでくれない
  • fill_passwordオプションの意味が本家と逆の意味になっている。そのためLiteはpasswordのデフォルトの動作も逆になっている。
  • selectedが追加されるときにタグの最後に「/」が強制的に追加される

このくらい?オプション関係は真面目に検証してないのでもしかしたら色々違いが出てくるかも。