以下のようなベンチマークを書いてみた。$aと$bは1or0とするとき、$aと$bが両方1であることを評価する。test0, test2, test3 は本質的に同じだと思うけど、test1だけは、$a == 1の評価の結果にかかわらずと$b == 1を評価するので、どんな入力があっても2回評価を行うため遅くなると思われる。
$ cat benchmark_andor.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use Benchmark qw/cmpthese timethese/;
my $count = 10000000;
cmpthese(
timethese($count,
{
'0-0-1' => 'test0(0,0);',
'0-1-1' => 'test0(0,1);',
'0-2-2' => 'test0(1,0);',
'0-3-2' => 'test0(1,1);',
'1-0-2' => 'test1(0,0);',
'1-1-2' => 'test1(0,1);',
'1-2-2' => 'test1(1,0);',
'1-3-2' => 'test1(1,1);',
'2-0-1' => 'test2(0,0);',
'2-1-1' => 'test2(0,1);',
'2-2-2' => 'test2(1,0);',
'2-3-2' => 'test2(1,1);',
'3-0-1' => 'test3(0,0);',
'3-1-1' => 'test3(0,1);',
'3-2-2' => 'test3(1,0);',
'3-3-2' => 'test3(1,1);',
}
)
);
exit;
sub test0
{
my $a = shift;
my $b = shift;
if ($a != 1 || $b != 1) {
return 0;
} else {
return 1;
}
}
sub test1
{
my $a = shift;
my $b = shift;
if ($a == 1 && $b == 1) {
return 1;
} else {
return 0;
}
}
sub test2
{
my $a = shift;
my $b = shift;
if ($a == 1) {
if ($b == 1) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
sub test3
{
my $a = shift;
my $b = shift;
if ($a != 1) {
return 0;
} else {
if ($b != 1) {
return 0;
} else {
return 1;
}
}
}
__END__
a a
0 1
b 0 0 0
b 1 0 1
で結果が以下。X-Y-ZのZは評価する回数、Yは引数のタイプ、Xは評価方法に付けられたラベル。期待される結果はZ=2はZ=1に比べて遅くなるはずだが、そうではない結果が得られている。perlでプロファイラ使うのはどうすりゃいいんだ。
$ perl benchmark_andor.pl
Benchmark: timing 10000000 iterations of 0-0-1, 0-1-1, 0-2-2, 0-3-2, 1-0-2, 1-1-2, 1-2-2, 1-3-2, 2-0-1, 2-1-1, 2-2-2, 2-3-2, 3-0-1, 3-1-1, 3-2-2, 3-3-2...
0-0-1: 12 wallclock secs ( 6.24 usr + 0.00 sys = 6.24 CPU) @ 1602564.10/s (n=10000000)
0-1-1: 13 wallclock secs ( 7.07 usr + 0.00 sys = 7.07 CPU) @ 1414427.16/s (n=10000000)
0-2-2: 13 wallclock secs ( 6.86 usr + 0.00 sys = 6.86 CPU) @ 1457725.95/s (n=10000000)
0-3-2: 16 wallclock secs ( 8.02 usr + 0.01 sys = 8.03 CPU) @ 1245330.01/s (n=10000000)
1-0-2: 16 wallclock secs ( 8.48 usr + 0.00 sys = 8.48 CPU) @ 1179245.28/s (n=10000000)
1-1-2: 16 wallclock secs ( 7.93 usr + 0.00 sys = 7.93 CPU) @ 1261034.05/s (n=10000000)
1-2-2: 17 wallclock secs ( 7.96 usr + 0.01 sys = 7.97 CPU) @ 1254705.14/s (n=10000000)
1-3-2: 13 wallclock secs ( 7.00 usr + 0.00 sys = 7.00 CPU) @ 1428571.43/s (n=10000000)
2-0-1: 15 wallclock secs ( 7.71 usr + 0.01 sys = 7.72 CPU) @ 1295336.79/s (n=10000000)
2-1-1: 15 wallclock secs ( 7.56 usr + 0.01 sys = 7.57 CPU) @ 1321003.96/s (n=10000000)
2-2-2: 17 wallclock secs ( 8.14 usr + 0.00 sys = 8.14 CPU) @ 1228501.23/s (n=10000000)
2-3-2: 17 wallclock secs ( 7.70 usr + 0.00 sys = 7.70 CPU) @ 1298701.30/s (n=10000000)
3-0-1: 15 wallclock secs ( 6.85 usr + 0.00 sys = 6.85 CPU) @ 1459854.01/s (n=10000000)
3-1-1: 13 wallclock secs ( 6.48 usr + 0.02 sys = 6.50 CPU) @ 1538461.54/s (n=10000000)
3-2-2: 18 wallclock secs ( 8.32 usr + 0.00 sys = 8.32 CPU) @ 1201923.08/s (n=10000000)
3-3-2: 16 wallclock secs ( 8.41 usr + 0.00 sys = 8.41 CPU) @ 1189060.64/s (n=10000000)
Rate 1-0-2 3-3-2 3-2-2 2-2-2 0-3-2 1-2-2 1-1-2 2-0-1 2-3-2 2-1-1 0-1-1 1-3-2 0-2-2 3-0-1 3-1-1 0-0-1
1-0-2 1179245/s -- -1% -2% -4% -5% -6% -6% -9% -9% -11% -17% -17% -19% -19% -23% -26%
3-3-2 1189061/s 1% -- -1% -3% -5% -5% -6% -8% -8% -10% -16% -17% -18% -19% -23% -26%
3-2-2 1201923/s 2% 1% -- -2% -3% -4% -5% -7% -7% -9% -15% -16% -18% -18% -22% -25%
2-2-2 1228501/s 4% 3% 2% -- -1% -2% -3% -5% -5% -7% -13% -14% -16% -16% -20% -23%
0-3-2 1245330/s 6% 5% 4% 1% -- -1% -1% -4% -4% -6% -12% -13% -15% -15% -19% -22%
1-2-2 1254705/s 6% 6% 4% 2% 1% -- -1% -3% -3% -5% -11% -12% -14% -14% -18% -22%
1-1-2 1261034/s 7% 6% 5% 3% 1% 1% -- -3% -3% -5% -11% -12% -13% -14% -18% -21%
2-0-1 1295337/s 10% 9% 8% 5% 4% 3% 3% -- -0% -2% -8% -9% -11% -11% -16% -19%
2-3-2 1298701/s 10% 9% 8% 6% 4% 4% 3% 0% -- -2% -8% -9% -11% -11% -16% -19%
2-1-1 1321004/s 12% 11% 10% 8% 6% 5% 5% 2% 2% -- -7% -8% -9% -10% -14% -18%
0-1-1 1414427/s 20% 19% 18% 15% 14% 13% 12% 9% 9% 7% -- -1% -3% -3% -8% -12%
1-3-2 1428571/s 21% 20% 19% 16% 15% 14% 13% 10% 10% 8% 1% -- -2% -2% -7% -11%
0-2-2 1457726/s 24% 23% 21% 19% 17% 16% 16% 13% 12% 10% 3% 2% -- -0% -5% -9%
3-0-1 1459854/s 24% 23% 21% 19% 17% 16% 16% 13% 12% 11% 3% 2% 0% -- -5% -9%
3-1-1 1538462/s 30% 29% 28% 25% 24% 23% 22% 19% 18% 16% 9% 8% 6% 5% -- -4%
0-0-1 1602564/s 36% 35% 33% 30% 29% 28% 27% 24% 23% 21% 13% 12% 10% 10% 4% --