perlでBenchmarkテスト

perlの色々な関数や処理の実行時間をBenchmarkモジュールを使って計測・比較してみました。

スカラ変数と配列によるアクセス時間の差

実用性の高い、localtimeによる日時取得を例にします。
use Benchmark;
timethese 1_024_000, {
operation1 => sub {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon++;
},
operation2 => sub {
($mday,$mon,$year) = (localtime(time))[3..5];
$year += 1900;
$mon++;
},
operation3 => sub {
@times = localtime(time);
$times[5] += 1900;
$times[4]++;
},
operation4 => sub {
@times = (localtime(time))[3..5];
$times[2] += 1900;
$times[1]++;
},
};

●実行結果
Benchmark: timing 1024000 iterations of operation1, operation2, operation3, oper
ation4…
operation1: 3 wallclock secs ( 3.72 usr + 0.00 sys = 3.72 CPU) @ 275342.83/s
(n=1024000)
operation2: 5 wallclock secs ( 4.22 usr + 0.02 sys = 4.24 CPU) @ 241737.49/s
(n=1024000)
operation3: 7 wallclock secs ( 5.53 usr + 0.00 sys = 5.53 CPU) @ 185171.79/s
(n=1024000)
operation4: 5 wallclock secs ( 4.80 usr + 0.00 sys = 4.80 CPU) @ 213466.75/s
(n=1024000)

●評価
まず配列よりも個別にスカラ変数を用いた方が格段にアクセスの早いことが分かります。配列はヘッド時間の分、読み出しに時間がかかるのでしょう。forやwhileなどで、同じ構造のデータに順次アクセスしたいとき以外は、個別にスカラ変数を用いたほうが良いようです。

スカラ変数を用いた場合は、operation2のように必要な部分だけを切り出すよりも、operation1のように全て読み込んでしまう方が早くなっています。要素の数が多かったり、1つの変数に代入されるデータ量が多くてメモリを浪費したりする場合以外は、配列内の全データを読み出してしまうのが得策のようです。

逆に、配列でデータを管理する場合 (operation3と4) には、配列の数が小さいほど、アクセスは早くなっています。これもヘッド時間の関係でしょうか。

サブルーチン

サブルーチンは、何度も読み出す処理を個別に書くことができ、プログラムの再利用性が上がるほか、ソースを綺麗にまとめてくれます。しかし、その実行時間にはかなりの差がつくようです。
なおSTD_OUTに出力すると、実行結果が見づらいので、適当な出力OUTに出力しています。
use Benchmark;
timethese 1_024_000, {
operation1 => sub {
print OUT "this is header";
print OUT "this is main";
print OUT "this is footer";
},
operation2 => sub {
print OUT &header;
print OUT "this is main";
print OUT &footer;
},
};
sub header { return "this is header"; }
sub footer { return "this is footer"; }

●実行結果
Benchmark: timing 1024000 iterations of operation1, operation2…
operation1: 2 wallclock secs ( 0.67 usr + 0.00 sys = 0.67 CPU) @ 1526080.48/s
(n=1024000)
operation2: 5 wallclock secs ( 4.58 usr + 0.02 sys = 4.59 CPU) @ 222899.43/s
(n=1024000)

●評価
なんと、実行時間に7倍もの差がついてしまいました。

1箇所からしか呼び出されない処理はサブルーチンにしない方がよい、と言われますが、これだけ実行時間に差がつくのですから当然ですね。

●講評
perlはプログラマーの書き方によって、かなり実行時間に差がついてくる言語だと実感しました。

実行時間はそのままサーバーへの負荷にかかわってきますから、ベンチマークテストによって最適な記述をすることは欠かせないものだと思います。

カテゴリー: perl   パーマリンク

コメントをどうぞ

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>