もしあなたのperl HTTPハンドラが「可能ならgzipしたコンテンツを返したい」と思うなら、Compress::Zlibを使うだろう。だがそれを毎回eval + requireするのは正直無駄だ。なぜならプログラムが起動した時にすでにそれを毎回行うのかどうかすでにわかっているからだ。
Compress::Zlibがあった場合はHAVE_ZLIBは定数で真なのでifの評価ではAccept-Encodingヘッダの評価だけにとどまる。
毎回eval + requireをするのと比べると大分かかるコストが違うのがわかると思う。
どういう評価されるのかわからない時は perl -MO=Deparse ... で評価するといいんだぜ!
sub psgi_response {こんな場合は定数にするべし
my ($self, $content) = @_;
my $req = $self->req;
my $res = $self->res;
if ($req->header('Accept-Encoding') =~ /\bgzip\b/i) { if (eval { require Compress::Zlib }) { $res->header('Content-Encoding' => 'gzip'); $content = Compress::Zlib::memGzip($content);
}
}
... }
use constant HAVE_ZLIB => eval { require Compress::Zlib };これで何が違うかというとCompress::Zlibがなかった場合はHAVE_ZLIBが定数で偽と判断されるので、ifのブロック全体がそもそも評価される対象と見なされない(constant folding)
sub psgi_repsonse {
my ($self, $content) = @_;
my $req = $self->req;
my $res = $self->res;
if (HAVE_ZLIB && $req->header('Accept-Encoding') =~ /\bgzip\b/i) {
$res->header('Content-Encoding' => 'gzip');
$content = Compress::Zlib::memGzip($content);
}
...
}
Compress::Zlibがあった場合はHAVE_ZLIBは定数で真なのでifの評価ではAccept-Encodingヘッダの評価だけにとどまる。
毎回eval + requireをするのと比べると大分かかるコストが違うのがわかると思う。
どういう評価されるのかわからない時は perl -MO=Deparse ... で評価するといいんだぜ!
コメント