Подтвердить что ты не робот

Почему Array.reverse_each быстрее, чем Array.reverse.each

Я почти не использую метод reverse_each, вместо этого я вызываю reverse.each, когда мне нужно пересечь массив назад. Таким образом, я просто сделал некоторый бенчмаркинг и, по-видимому, reverse_each значительно быстрее, чем reverse.each.

  • Это потому, что есть элемент времени, связанный с созданием обратного массива перед его повторением при использовании reverse.each?

Однако в моем примере (ниже) из 10 миллионов итераций TIME(reverse) + TIME(each) - TIME(reverse.each) ~ 1.2 seconds для массива размера 4. И эта разница во времени более или менее остается стабильной независимо от размера массива. Я тестировал его на 100 элементов.

  • Что объясняет это одно второе различие?

require 'benchmark'

number = 10000000
arr = (1..4).to_a

Benchmark.bm(13) do |x|
    x.report("reverse.each") { number.times { arr.reverse.each {|x| x} } }
    x.report("reverse_each") { number.times { arr.reverse_each {|x| x} } }
    x.report("reverse")      { number.times { arr.reverse } }             
    x.report("each")         { number.times { arr.each {|x| x} } }        
end
4b9b3361

Ответ 1

Я бы определенно сказал, что это связано со временем, связанным с созданием обратного массива! Вы только пробовали очень маленькие массивы (массив с 100 элементами по-прежнему представляет собой небольшой массив). Если вы попытаетесь с большими массивами (например, 10k элементов), я думаю, вы действительно заметите разницу.

Ответ 2

Это довольно просто:

  • reverse.each создает новый массив, затем зацикливает каждый элемент

  • циклы reverse_each в обратном порядке (промежуточный массив не создан)

См. Исходный код в документе: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-reverse_each