each_index_widthは遅い

2023.5.3

ことの発端

↓AOJのこの問題を解いたらタイムアウトになった

https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/3/ITP1_3_B

タイムアウトになるコード

input = readlines
input.pop
input.each_with_index { |n, i| puts "Case #{i}: #{n}"}

タイムアウトにならないコード

input = readlines
i = 0
while (input[i].to_i != 0) do
  puts "Case #{i+1}: #{input[i]}"
  i = i + 1
end

自分でイテレータを用意して、whileで回すと速い

検証コードで速度を比較

each_width_index

require 'benchmark'

array = Array.new(100000, "hoge")

result = Benchmark.realtime do
  # 比較対象
  array.each_with_index {|s, i|}

end
puts "処理概要 #{result}s"

処理概要 0.0042760001961141825s

each + イテレータ

require 'benchmark'

array = Array.new(100000, "hoge")

result = Benchmark.realtime do
  # 比較対象
  i = 0
  array.each { i += 1 }

end
puts "処理時間 #{result}s"

処理時間 0.0037060000468045473s

while + イテレータ

require 'benchmark'

array = Array.new(100000, "hoge")

result = Benchmark.realtime do
  # 比較対象
  i = 0
  i += 1 while (i < 100000);

end
puts "処理時間 #{result}s"

処理時間 0.0012109999269247055s

結論

whileが一番速い

  • each_width_index:4.2(ms)
  • each:3.7(ms)
  • while:1.2(ms)