Rubyのfor文とeachメソッドの実行速度を比較してみた
Rubyを学習していて、「for文はeachメソッドのシンタックスシュガー」だということを知りました。
個人的にはPythonと書き方が似ているfor文を使いたいのですが、シンタックスシュガーということは実行時にeachメソッドに置き換えてから実行しているということになります。C言語にもシンタックスシュガーはあるのですが、コンパイル時に最適化されているはずなので特に気にしていませんでした。しかし、インタプリタ言語であるRubyだとその分処理に時間がかかるのでは?と疑問に思ったので調べてみました。
計測方法
1から10までの合計を求めるループ処理を1万回実行した時の時間を計測します。
キャッシュ対策として1から10までを数える変数と、合計を求める変数はループ処理毎に変えます。
コードに書くと次の様なイメージになります。
sum_1 = 0
for a_1 in (1..10)
sum_1 += a_1
end
sum_2 = 0
for a_2 in (1..10)
sum_2 += a_2
end
#省略
sum_9999 = 0
for a_9999 in (1..10)
sum_9999 += a_9999
end
sum_10000 = 0
for a_10000 in (1..10)
sum_10000 += a_10000
end
これを手動で書くのは手間なので、ソースを書きました。ファイル出力はリダイレクトで行います。
MAX_NUM = 10000
LOOP_TYPE_FOR = true
for num in (1..MAX_NUM)
puts "sum_#{num} = 0"
if LOOP_TYPE_FOR
puts "for a_#{num} in (1..10)"
else
puts "(1..10).each do |a_#{num}|"
end
puts " sum_#{num} += a_#{num}"
puts "end"
end
計測するためのコマンド
計測にはtimeコマンドのuser項目を利用します。
計測結果
for文とeachメソッドのテストプログラムを10回計測し、集計すると下表の様になりました。
中央値は値を降順か昇順に並べた時の真ん中の値です。統計学の本を読んだら平均値より信頼できる値だと書いていたので載せています。
集計項目 | for文(sec) | eachメソッド(sec) |
---|---|---|
平均 | 1.1830 | 0.5845 |
最大 | 1.2330 | 0.6070 |
最小 | 1.1660 | 0.5690 |
中央値 | 1.1765 | 0.5815 |
当初の予想通りの結果になってしまいました。
for文とeachメソッドを1万回実行した時の速度の差が約0.6secですから、for文を一回実行することで発生する速度差は次の計算で求めれます。
0.6(sec) / 10000 = 0.00006(sec)
ミリ秒に変換すると0.06ms。マイクロ秒だと60μsになります。
おまけ
もう答えは出ているのですが、どうしてもeach文使いたくありません。
悪あがきとして、私がRubyを使う理由である「Ruby on Rails」ではどちらを使っているかも調べてみました。
Ruby on Railsのソースはこちらから取得しました。 https://github.com/rails/rails
次のコマンドを実行して.rbファイルに含まれる「.each」と「for 」の数を集計してみました。
find . -name ”*.rb” | xargs grep -n "for " > grep_for-1.txt
find . -name ”*.rb” | xargs grep -n ".each" > grep_each-1.txt
すると次の様な結果になりました。
- .eachのヒット数:2308
- forのヒット数:3585
forの方が多い!?ワンチャンあるか!!
と、期待に胸を膨らませてforの集計結果を見てると、コメントやログ出力時の文面に使われている"for"がヒットしているだけで、構文としてforは全く使われていませんでした。
最後に
当初の予想通りの結果になってしまいました。
Rubyの創造神であるまつもとゆきひろ監修の『たのしいRuby 第5版』でも、for文でなくeachメソッドを使う様に勧めていました。
ですが、どうしてもeach文を使いたくなくて、神を否定する根拠が欲しくて今回調査をしてみました。
結果は敗北です。やはり、一般人が神に挑むのは無謀でした。
「あれはまちがいだった。あれはまちがいだった。
世界を変えるための呪文を本屋で探そうとしたのは間違いだった。
どこかの誰かが作った呪文を求めたのは間違いだった。
僕は僕だけの、自分専用の呪文を作らなくては駄目だった。」
ーー穂村弘『短歌という爆弾』
引用:『たのしいRuby 第5版』
呪文を自作できない、創造神になれない私は神に従うだけです。
以上です。
ここまで読んでいただき、ありがとうございました。