Benchmark - ベンチマーク(性能比較)を行う
Benchmarkモジュールを使用すると、ベンチマーク(性能比較)を行うことができます。
# モジュールの読み込みと関数のインポート use Benchmark qw/timethese cmpthese/;
timethese関数を実行すると各関数の性能情報を取得できます。これをcompthese関数の引数に指定すると、標準出力に比較結果が表示されます。
# 性能の比較
my $result = timethese($count, {
name1 => sub {
# 実行したい処理1
},
name2 => sub {
# 実行したい処理2
},
name3 => sub {
# 実行したい処理3
},
});
cmpthese $result;
ベンチマークを行うサンプルです。精度を上げるために実行回数をある程度増やす必要があります。このサンプルでは10000回実行しています。
# ベンチマークのサンプル
my $result = timethese(10000, {
loop1 => sub {
my $i = 0;
while ($i < 1500) {
$i++;
}
},
loop2 => sub {
my $i = 0;
while ($i < 1000) {
$i++;
}
},
loop3 => sub {
my $i = 0;
while ($i < 500) {
$i++;
}
},
});
cmpthese $result;
下記の出力結果になります。loop3はloop1と比較して3倍近く速いことが確認できます。
# ベンチマークの出力結果
Benchmark: timing 10000 iterations of loop1, loop2, loop3...
loop1: 4 wallclock secs ( 2.98 usr + 0.00 sys = 2.98 CPU) @ 3351.21/s (n=10000)
loop2: 2 wallclock secs ( 1.75 usr + 0.00 sys = 1.75 CPU) @ 5714.29/s (n=10000)
loop3: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 9699.32/s (n=10000)
Rate loop1 loop2 loop3
loop1 3351/s -- -41% -65%
loop2 5714/s 71% -- -41%
loop3 9699/s 189% 70% --
Benchmarkモジュールに関するFAQ
Q. Benchmarkモジュールは実際の処理時間を計算していますか。
A. wallclockで表示される時間は実際にかかった時間です。@ の後ろの値は「試行回数/CPU時間」で計算されます。
@ の後ろに掲載される値は「試行回数/CPU時間」という計算式で計算されます。CPU時間はそのプロセスが使用したCPUの時間なので、データベースアクセスなどのI/O待ちや子プロセスを実行される時間などは含まれません。またsleep関数を実行している場合もCPUを使用していないので実行時間に含まれません。
つまりI/Oや子プロセスを呼び出しを含むベンチマークをとる場合には @ の後ろの値を参考にすることはできないということです。cmptheseで比較される値も「試行回数/CPU時間」ですので、表示される値をそのまま評価に利用することはできません。
I/Oや子プロセスの実行を行っている場合はwallclockに表示されている値を見る必要があります。ですが、ほとんどの場合はプログラムのアルゴリズムの評価を行う目的でBenchmarkモジュールを利用すると思いますので、cmptheseで比較される値を目安にしてよいでしょう。
Perlゼミ

