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で比較される値を目安にしてよいでしょう。