id:cuzic さんが qr が有利な実例をあげてくださいました。ありがとうございます。
あれ?なんで自分で確かめたときはアドバンテージを感じなかったんだろう,と思い,cuzic さんのコードも混ぜてベンチマークとってみました。今回は恥ずかしながらソース付きです。
#!/usr/bin/perl
use strict;
use Benchmark qw(:all);
timethese(50, {
'test_1_qq' => \&test_1_qq,
'test_1_qr' => \&test_1_qr,
'test_2_qq' => \&test_2_qq,
'test_2_qr' => \&test_2_qr,
});
my @strs = qw(a b c);
sub test_1_qq {
my $c = 0;
foreach my $i (1..10000) {
my $qq = qq/$i/;
if ('a' =~ m/$qq/) {
$c ++;
}
if ('b' =~ m/$qq/) {
$c ++;
}
if ('c' =~ m/$qq/) {
$c ++;
}
}
}
sub test_1_qr {
my $c = 0;
foreach my $i (1..10000) {
my $qr = qr/$i/;
if ('a' =~ m/$qr/) {
$c ++;
}
if ('b' =~ m/$qr/) {
$c ++;
}
if ('c' =~ m/$qr/) {
$c ++;
}
}
}
sub test_2_qq {
my $c = 0;
foreach my $i (1..10000) {
my $qq = qq/$i/;
foreach my $str (@strs) {
if ($str =~ m/$qq/) {
$c ++;
}
}
}
}
sub test_2_qr {
my $c = 0;
foreach my $i (1..10000) {
my $qr = qr/$i/;
foreach my $str (@strs) {
if ($str =~ m/$qr/) {
$c ++;
}
}
}
}test_1 は test_2 とほぼ同じですが,cuzic さんのように,比較する文字列を手で展開したものです。
この結果が,
test_1_qq: 26 wallclock secs (26.02 usr + 0.00 sys = 26.02 CPU) @ 1.92/s (n=50) test_1_qr: 16 wallclock secs (16.35 usr + 0.00 sys = 16.35 CPU) @ 3.06/s (n=50) test_2_qq: 1 wallclock secs ( 1.33 usr + 0.02 sys = 1.35 CPU) @ 37.04/s (n=50) test_2_qr: 16 wallclock secs (16.02 usr + 0.02 sys = 16.04 CPU) @ 3.12/s (n=50)
たしかに test_1_qr のほうが速いですね…って…
ちょwww
test_2_qq (not qr) ありえなさすぎ。
これは Perl が最適化してくれた(ループ内で o 扱いした?)と考えていいんですかね。このコードおかしいよ,というつっこみがあれば大歓迎します。