我进行了一些基准测试:
require 'benchmark'
words = File.open('/usr/share/dict/words', 'r') do |file|
file.each_line.take(1_000_000).map(&:chomp)
end
Benchmark.bmbm(20) do |x|
GC.start
x.report(:map) do
words.map do |word|
word.size if word.size > 5
end.compact
end
GC.start
x.report(:each_with_object) do
words.each_with_object([]) do |word, long_sizes|
long_sizes << word.size if word.size > 5
end
end
end
输出(ruby 2.3.0):
Rehearsal --------------------------------------------------------
map 0.020000 0.000000 0.020000 ( 0.016906)
each_with_object 0.020000 0.000000 0.020000 ( 0.024695)
----------------------------------------------- total: 0.040000sec
user system total real
map 0.010000 0.000000 0.010000 ( 0.015004)
each_with_object 0.020000 0.000000 0.020000 ( 0.024183)
我不太理解它,因为我认为each_with_object
应该更快:它只需要1个循环和1个新对象来创建一个新数组,而不是在组合map
和compact
时需要2个循环和2个新对象。
有什么想法吗?
long_words << word
会不时地导致内存分配。 - Pavel Mikhailyukmap
/compact
更快但使用更多内存,而each_with_object
则较慢但消耗较少内存。 - Stefanwords.select { |word| word.size > 5 }
比你提供的两个示例更短、更合乎逻辑和更快。 - Eric Duminilwords.map{|w| w.size }.select{|s| s > 5}
比起你的方法慢 :D - Eric Duminil