Всякий раз, когда вы обнаруживаете, что кто-то утверждает, что что-то является самым быстрым в этом типе примитивной рутины, мне всегда интересно подтверждать это, потому что без подтверждения большинство из нас на самом деле просто гадают.Итак, я взял все методы здесь и протестировал их.
Я взял массив из 120 ссылок, извлеченных из веб-страницы, которые мне нужно было сгруппировать по количеству, и реализовал все это с помощью секунды = Benchmark.realtime.делай петлю и получай все время.
Предположим, что ссылки - это имя массива, который мне нужно сосчитать:
#0.00077
seconds = Benchmark.realtime do
counted_links = {}
links.each { |e| counted_links[e] = links.count(e) if counted_links[e].nil?}
end
seconds
#0.000232
seconds = Benchmark.realtime do
counted_links = {}
links.sort.group_by {|x|x}.each{|x,y| counted_links[x] = y.size}
end
#0.00076
seconds = Benchmark.realtime do
Hash[links.uniq.map{ |i| [i, links.count(i)] }]
end
#0.000107
seconds = Benchmark.realtime do
links.inject(Hash.new(0)) {|h, v| h[v] += 1; h}
end
#0.000109
seconds = Benchmark.realtime do
links.each_with_object(Hash.new(0)) {|e, h| h[e] += 1}
end
#0.000143
seconds = Benchmark.realtime do
links.inject(Hash.new(0)) { |h, e| h[e] += 1 ; h }
end
А затем немного рубина, чтобы выяснить ответ:
times = [0.00077, 0.000232, 0.00076, 0.000107, 0.000109, 0.000143].min
==> 0.000107
Итак, самый быстрый метод, конечно же, ymmv:
links.inject(Hash.new(0)) {|h, v| h[v] += 1; h}