読者です 読者をやめる 読者になる 読者になる

HTML::Template only VS HTML::FillInForm

さて、こうなってくると、毎度おなじみベンチマーク
今回は、HTML::Template(test1)とTemplate::Tool(test2)ということにしました。その結果は、以下のとおりです。

HTML::FillInForm便利!って話なんだが、確かに便利そう。ただ気になるのは、HTML::Parserがどの程度の違いを出すかということ。(パーサって得てして重いという先入観が。データを全部解析するんだし。)なんだかベンチマークがはやっているらしいので(いや、そういうことじゃないが)私もベンチマークに挑戦してみた。

まずはベンチ用コード。

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark;
use CGI;
use HTML::Template;
use HTML::FillInForm;

my $q = CGI->new;
$q->param("text","text field");
$q->param("checkbox","checkbox2","checkbox5");
$q->param("select","select3");

Benchmark::timethese(1000,{
	"HTML::Template" => ?&HTML_Template,
	"HTML::FillInForm" => ?&HTML_FillInForm
	}
);

sub HTML_Template {
	my $tmpl = HTML::Template->new(
		filename => "./HTML_Template.tmpl",
		asociate => $q
		);
	
	$tmpl->param( "checkbox_".$_, 'checked="checked"' )
		foreach( $q->param("checkbox") );
	$tmpl->param( "select_".$_, 'selected="selected"' )
		foreach( $q->param("select") );
	
	$tmpl->output;
}

sub HTML_FillInForm {
	my $tmpl = HTML::Template->new( filename => "./HTML_FillInForm.tmpl" );
	my $html = $tmpl->output;
	my $fif = HTML::FillInForm->new;
	
	$fif->fill(
		scalarref => ?$html,
		fobject => $q
	);
}

HTML_Templateサブルーチン内のforeach行でcheckedなりselectedをセットしている。で、普通の変数としてHTML::Template側から処理を加える訳だ。HTML::FillInFormの場合はこれが不要で、ラクチンと言う訳。サブルーチン内では、通常はprintすることでデータを得るのだが、今回はベンチなので処理するだけ処理して終わっている。

この辺の違いから、テンプレートにも若干の違いがある。別にCGIで動かす訳ではないのだけれど、実践に近い形にするために、以下のテンプレートを用意してみた。

(HTML_Template.tmpl)

<form action="bench.cgi" method="post">
	<div><input type="text" name="text" value="<TMPL_VAR text>" size="60" /></div>
	<div><input type="checkbox" name="checkbox" value="checkbox1" <TMPL_VAR checkbox_checkbox1> />checkbox1</div>
	<div><input type="checkbox" name="checkbox" value="checkbox2" <TMPL_VAR checkbox_checkbox2> />checkbox2</div>
	<div><input type="checkbox" name="checkbox" value="checkbox3" <TMPL_VAR checkbox_checkbox3> />checkbox3</div>
	<div><input type="checkbox" name="checkbox" value="checkbox4" <TMPL_VAR checkbox_checkbox4> />checkbox4></div>
	<div><input type="checkbox" name="checkbox" value="checkbox5" <TMPL_VAR checkbox_checkbox5> />checkbox5</div>
	<div>
		<select name="select">
			<option value="select1" <TMPL_VAR select_select1>>select1</option>
			<option value="select2" <TMPL_VAR select_select2>>select2</option>
			<option value="select3" <TMPL_VAR select_select3>>select3</option>
		</select>
	</div>
	<div>
		<input type="submit" value="SUBMIT" />
	</div>
</form>

(HTML_FillInForm.tmpl)

<form action="bench.cgi" method="post">
	<div><input type="text" name="text" value="" size="60" /></div>
	<div><input type="checkbox" name="checkbox" value="checkbox1" />checkbox1</div>
	<div><input type="checkbox" name="checkbox" value="checkbox2" />checkbox2</div>
	<div><input type="checkbox" name="checkbox" value="checkbox3" />checkbox3</div>
	<div><input type="checkbox" name="checkbox" value="checkbox4" />checkbox4</div>
	<div><input type="checkbox" name="checkbox" value="checkbox5" />checkbox5</div>
	<div>
		<select name="select">
			<option value="select1">select1</option>
			<option value="select2">select2</option>
			<option value="select3">select3</option>
		</select>
	</div>	<div>
		<input type="submit" value="SUBMIT" />
	</div>
</form>

HTML_FillInForm.tmplのほうが、checkedやselectedのハンドリング用変数がなくすっきり。

では、実際にベンチをとった結果は…

Benchmark: timing 1000 iterations of HTML::FillInForm, HTML::Template...
HTML::FillInForm: 11 wallclock secs (10.23 usr +  0.21 sys = 10.44 CPU) @ 95.79/s (n=1000)
HTML::Template:  7 wallclock secs ( 6.49 usr +  0.15 sys =  6.64 CPU) @ 150.60/s (n=1000)

倍とは言わないが、やはり差は出る。また、妙な変数が無くてすっきりなのは良いのだが、逆にあった方が細かな制御が可能という部分もあるだろう。状況に応じて、使い分ける形になるだろうか。

なお、一応上記関数の出力結果も書いておこう。

HTML::Template

<form action="bench.cgi" method="post">
        <div><input type="text" name="text" value="" size="60" /></div>
        <div><input type="checkbox" name="checkbox" value="checkbox1"  />checkbox1</div>
        <div><input type="checkbox" name="checkbox" value="checkbox2" checked="checked" />checkbox2</div>
        <div><input type="checkbox" name="checkbox" value="checkbox3"  />checkbox3</div>
        <div><input type="checkbox" name="checkbox" value="checkbox4"  />checkbox4</div>
        <div><input type="checkbox" name="checkbox" value="checkbox5" checked="checked" />checkbox5</div>
        <div>
                <select name="select">
                        <option value="select1" >select1</option>
                        <option value="select2" >select2</option>
                        <option value="select3" selected="selected">select3</option>
                </select>
        </div>
        <div>
                <input type="submit" value="SUBMIT" />
        </div>
</form>

HTML_FillInForm

<form action="bench.cgi" method="post">
        <div><input size="60" type="text" value="text field" name="text" /></div>
        <div><input type="checkbox" value="checkbox1" name="checkbox" />checkbox1</div>
        <div><input checked="checked" type="checkbox" value="checkbox2" name="checkbox" />checkbox2</div>
        <div><input type="checkbox" value="checkbox3" name="checkbox" />checkbox3</div>
        <div><input type="checkbox" value="checkbox4" name="checkbox" />checkbox4</div>
        <div><input checked="checked" type="checkbox" value="checkbox5" name="checkbox" />checkbox5</div>
        <div>
                <select name="select">
                        <option value="select1">select1</option>
                        <option value="select2">select2</option>
                        <option selected="selected" value="select3">select3</option>
                </select>
        </div>
        <div>
                <input type="submit" value="SUBMIT" />
        </div>
</form>

ともに望んだ結果を得られている。