1
0

More than 1 year has passed since last update.

Rubyの繰り返し処理の速さをベンチマークで調べてみた

Last updated at Posted at 2022-11-03

はじめに

Rubyの繰り返し処理の速さが気になったのでベンチマークで調べてみました。
whileを使うと速いと聞いたので、他の繰り返し処理も使い、実際に検証してみました。
Rubyのモジュールとして提供されているBenchmarkを使用してプログラム実行時のCPU処理にかかった時間を知ることができます。

繰り返す内容

1から3,000,000までの範囲の数値を加算していきます。
つまり↓のようになります
1 + 2 + 3 + 4 ・・・・・ 2999998 + 2999999 + 3000000 = 4,500,001,500,000

コード

Ruby
require 'benchmark'

Benchmark.benchmark(Benchmark::CAPTION, 10, Benchmark::FORMAT) do |x|
  x.report("each:         ") { 
    counter = 0
      [*1..3000000].each do |i|
        counter += i
  end
    }
  x.report("times:        ") { 
    counter = 0
      3000000.times do |i|
        counter += i + 1
  end 
    }

  x.report("each range:   ") { 
    counter = 0
      (1..3000000).each do |i|
        counter += i
  end
  }

  x.report("times simple: ") { 
    counter = 0
      (3000001).times do |i|
        counter += i
  end 
  }
  
 x.report("upto:         ") { 
    counter = 0
      1.upto(3000000) do |i|
        counter += i
  end
  }

  x.report("while:        ") { 
    counter,i = 0,1
      while i != 3000001 do
        counter += i
        i += 1
  end
  }
end

実行結果

                 user     system      total        real
each:           0.244779   0.016559   0.261338 (  0.261447)
times:          0.166149   0.000000   0.166149 (  0.166150)
each range:     0.154344   0.000083   0.154427 (  0.154438)
times simple:   0.153153   0.000066   0.153219 (  0.153221)
upto:           0.154999   0.000000   0.154999 (  0.155002)
while:          0.079974   0.000000   0.079974 (  0.079976)

上記からわかること

whileが一番速く、timesとuptoとeachがほぼ同じということがわかりました。
あとは[*1..3000000]と(1..3000000)やi + 1のように書き方により速度が変わることもわかりました。
特に[*1..3000000]にするとだいぶ速度が落ちるので、(1..3000000)を使うのを意識したいです。

ちなみに

ガウスの計算(足し算)を使うと計算が1回ですむので2〜3千倍速くなりました。
ガウスの計算(足し算)の公式:(初めの数+最後の数)×個数÷2
初めの数:1
最後の数:3,000,000
個数:3,000,000
つまり( 1 + 3000000) * ( 3000000 / 2 ) = 4,500,001,500,000
3000001 * 1500000 = 4,500,001,500,000

Ruby
require 'benchmark'

Benchmark.benchmark(Benchmark::CAPTION, 10, Benchmark::FORMAT) do |x|
   x.report("ガウス計算:") { 
     puts "計算結果は#{ ( 1 + 3000000 ) * ( 3000000 / 2 ) }" 
   }
end

実行結果

                 user     system      total        real
ガウス計算:       計算結果は4500001500000
ガウス計算:       0.000026   0.000000   0.000026 (  0.000026)

ガウスは偉大!

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0