はじめに
今回は7つの繰り返し条件式(for, while, each, until, times, upto, downto)を使ってそれぞれ検証します。
gem benchmark_driverを使います。
@scivola さん、アドバイスありがとうございます。
共通条件
- 繰り返し上限値:10000
- 前判定
- FizzBuzz条件式は全て同じ
実行コード
benchmark.rb
require 'benchmark_driver'
Benchmark.driver do |x|
n = 10000
x.report "#{n}回 for", %{
for i in 1..#{n} do
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
end
}
x.report "#{n}回 while", %{
i = 1
while i <= #{n} do
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
i += 1
end
}
x.report "#{n}回 each", %{
(1..#{n}).each { |i|
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
}
}
x.report "#{n}回 until", %{
i = 0
until i >= #{n}
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
i += 1
end
}
x.report "#{n}回 times", %{
#{n}.times do |i|
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
end
}
x.report "#{n}回 upto", %{
1.upto(#{n}) do |i|
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
end
}
x.report "#{n}回 downto", %{
#{n}.downto(1) do |i|
if i % 15 == 0
"FizzBuzz"
elsif i % 3 == 0
"Fizz"
elsif i % 5 == 0
"Buzz"
else
i
end
end
}
end
結果
一番早かったのがwhileでしたがuntilとどんぐりの背比べ程度の差でした。
Warming up --------------------------------------
10000回 for 819.214 i/s - 860.000 times in 1.049787s (1.22ms/i)
10000回 while 1.453k i/s - 1.460k times in 1.004510s (688.02μs/i)
10000回 each 946.035 i/s - 1.001k times in 1.058100s (1.06ms/i)
10000回 until 1.386k i/s - 1.480k times in 1.067445s (721.25μs/i)
10000回 times 918.016 i/s - 920.000 times in 1.002161s (1.09ms/i)
10000回 upto 867.162 i/s - 920.000 times in 1.060932s (1.15ms/i)
10000回 downto 854.204 i/s - 890.000 times in 1.041906s (1.17ms/i)
Calculating -------------------------------------
10000回 for 855.651 i/s - 2.457k times in 2.871499s (1.17ms/i)
10000回 while 1.424k i/s - 4.360k times in 3.061448s (702.17μs/i)
10000回 each 869.559 i/s - 2.838k times in 3.263725s (1.15ms/i)
10000回 until 1.393k i/s - 4.159k times in 2.985758s (717.90μs/i)
10000回 times 862.132 i/s - 2.754k times in 3.194408s (1.16ms/i)
10000回 upto 845.573 i/s - 2.601k times in 3.076020s (1.18ms/i)
10000回 downto 858.080 i/s - 2.562k times in 2.985737s (1.17ms/i)
Comparison:
10000回 while: 1424.2 i/s
10000回 until: 1392.9 i/s - 1.02x slower
10000回 each: 869.6 i/s - 1.64x slower
10000回 times: 862.1 i/s - 1.65x slower
10000回 downto: 858.1 i/s - 1.66x slower
10000回 for: 855.7 i/s - 1.66x slower
10000回 upto: 845.6 i/s - 1.68x slower