Skip to content

Instantly share code, notes, and snippets.

@simonoff
Last active December 30, 2015 06:49
Show Gist options
  • Select an option

  • Save simonoff/7792049 to your computer and use it in GitHub Desktop.

Select an option

Save simonoff/7792049 to your computer and use it in GitHub Desktop.
in_groups_of faster then each_slice ?!!!
a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
n = 1000000
Benchmark.bm do |x|
x.report('in_groups_of') { n.times { a.in_groups_of(7, false).select{|x| x.size == 7} } }
x.report('each_slice') { n.times { a.each_slice(7).select{|x| x.size == 7} } }
x.report('each_slice with result') { n.times { res = []; a.each_slice(7) {|x| res << x if x.size == 7 }; } }
end
# user system total real
#in_groups_of 4.690000 0.010000 4.700000 ( 4.745116)
#each_slice 5.730000 0.020000 5.750000 ( 5.823958)
#each_slice with result 4.270000 0.010000 4.280000 ( 4.378506)
@e1senh0rn
Copy link
Copy Markdown

jRuby:

                        user     system      total        real
in_groups_of            1.170000   0.070000   1.240000 (  0.633000)
each_slice              0.540000   0.020000   0.560000 (  0.230000)
each_slice with result  0.120000   0.000000   0.120000 (  0.094000)

@pahanix
Copy link
Copy Markdown

pahanix commented Dec 5, 2013

#in_groups_of не быстрее #each_slice

В твоем случае некорректно сравнивать #in_groups_of c #each_slice, потому что в первом случае #in_groups_of это обертка над #each_slice with result, а не просто #each_slice

В #each_slice дополнительно происходит инициализация Enumerator'a, а в #each_slice with result инициализации Enumerator'a не происходит

У тебя слишком маленький массив и большой кусок времени занимает именно инициализация Enumerator'a
Время складывается следующим образом

#in_groups_of вызов блока через each_slice with result + время на вызов метода с парочкой if'ов
#each_slice сначала инициализирует Enumerator, а потом делает вызов блока через each_slice with result
#each_slice with result не инициализирует Enumerator, а сразу делает вызов блока

Если увеличить массив, то все встанет на свои места

a = [*1..10000]
n = 1000
Benchmark.bm do |x|
  x.report('in_groups_of') { n.times { a.in_groups_of(7, false).select{|x| x.size == 7}  } }
  x.report('each_slice') { n.times { a.each_slice(7).select{|x| x.size == 7} } }
  x.report('each_slice with result') { n.times { res = []; a.each_slice(7) {|x| res << x if x.size == 7 }; } }
end

#                            user    system      total        real
# in_groups_of            1.850000   0.010000   1.860000 (  1.854990)
# each_slice              1.680000   0.000000   1.680000 (  1.676715)
# each_slice with result  1.670000   0.000000   1.670000 (  1.677719)

P.S. #select тут большой роли не играет, он сопоставим с #to_a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment