以下のようなベンチマークを書いてみた。$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% --