Ruby'ленивый' менее производительный, чем выделение огромных списков?

Я пытаюсь обработать большой список чисел:

require 'benchmark'

N = 999999

Benchmark.bm 10 do |bm|
   bm.report 'Eager:' do
 (0..N).select(&:even?).map{|x| x * x}.reduce(&:+)
   end  
   bm.report 'Lazy:' do
 (0..N).lazy.select(&:even?).map{|x| x * x}.reduce(&:+)
   end  
 end;

Насколько я понимаю, ленивая версия должна быть намного быстрее, потому что нетерпеливой версии нужно выделить два списка по полмиллиона элементов в каждом (один для select и один для map) пока ленивая версия все течет.

Тем не менее, когда я запускаю его, ленивая версия занимает более чем вдвое дольше, чем нетерпеливая! ( http://rextester.com/OTEX7399)

         user     system      total        real
Eager:       0.210000   0.010000   0.220000 (  0.216572)
Lazy:        0.580000   0.000000   0.580000 (  0.635091)

Как это может быть?

1 ответ

Решение

Я бы сказал, что Enumerator намного медленнее среднего уровня, чем память.

Об этом также сообщалось некоторое время назад, и член основной команды Ruby Юсуке Эндо сказал:

Перечислитель:: Ленивый не серебряная пуля; он устраняет накладные расходы на создание промежуточного массива, но имеет недостаток для вызова блока. К сожалению, последний намного больше, чем первый. Таким образом, в общем, Lazy имеет недостаток производительности.


Аналогия, о которой я только что подумал: представьте, что вы создаете мебель для друга.

  • Не ленивый: Вы строите все это, арендуете грузовик и едете к своему другу.

  • Ленивый: Вы строите маленький кусочек и едете на машине к другу. Вы строите следующий маленький кусочек и едете на машине к своему другу. Вы строите следующий маленький кусочек и едете на машине к своему другу. И так далее.

Да, аренда этого грузовика - это дополнительные расходы, но это ничто по сравнению с ездой снова и снова с вашим автомобилем.

Настоящая причина, по которой ленивость может сэкономить время, заключается в том, что после первых нескольких пьес ваш друг узнает, что вы переспали с его женой, и теперь вы больше не друзья, и он больше не хочет вашей дурацкой мебели и не строит оставшиеся кусочки вообще.

Другие вопросы по тегам