qr たしかにすごいが Perl の最適化はもっとすごい?
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 扱いした?)と考えていいんですかね。このコードおかしいよ,というつっこみがあれば大歓迎します。