北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

mapは遅いのか

絡まれたので絡み返してみますヽ(ω・ヽ)(ノ・ω)ノ ♪

ってことで、mapって遅いの? ほんとに?? 試しに計ってみました。

use Time::HiRes;
my @data  = 1 .. 1_000_000;
my $s = Time::HiRes::time();

# ...
# ここに、@dataの全要素を二倍するロジック
# ...

print Time::HiRes::time() - $s, "?n";

まずは、map関数。

@data = map {$_ * 2} @data;
結果:0.611232042312622 秒

で、foreach。

$_ *= 2 foreach(@data);
結果:0.166959047317505 秒

まあ、これはmap関数版の方は配列をコピーしてるから明らかに負けるでしょう。mapでも、$_をいじることで配列の中身を変更することができるので、次のコードも試してみました。

map {$_ *= 2} @data;
結果:0.445049047470093 秒

うひゃ、負けてる・・・。これなら同等の速度が出るのを期待していたんですが、mapの常習犯だけに、ショックな結果です。じゃあと、foreachで配列をコピーする"遅い版"を作ってみます。

push(@data2, $_ * 2) foreach(@data);
結果:0.381129026412964 秒

これだけやらせても、まだmapの方が遅い・・・。明らかに見やすくなる場合以外は、mapを使うべきではないみたいですね。*1

*1:と言っても、これはperl v5.8.6の結果なので、バージョンによっては変わるかも??