在迭代数组时map
比each
更快吗?两者之间有速度差异吗?
地图
result = arr.map {|a| a + 2}
每个
result = []
arr.each do |a|
result.push(a + 2)
end
答案 0 :(得分:8)
我想是的。
我已经尝试过这个测试
require "benchmark"
n=10000
arr=Array.new(10000,1)
Benchmark.bm do |x|
#Map
x.report do
n.times do
result = arr.map {|a| a + 2}
end
end
#Each
x.report do
n.times do
result = []
arr.each do |a|
result.push(a + 2)
end
end
end
end
我得到了这个时间
user system total real
5.790000 0.060000 5.850000 ( 5.846956)
8.210000 0.030000 8.240000 ( 8.233849)
似乎更快地映射
我看过这段视频http://confreaks.tv/videos/goruco2015-how-to-performance 她展示了许多红宝石配置文件和工具,如果你有兴趣改善你的表现,你会发现很多提示。
<强>加入强>
这对我来说是一种疯狂的行为!
require "benchmark"
n=10000
arr=Array.new(10000,1)
Benchmark.bm do |x|
#Map
x.report do
n.times do
result = arr.map {|a| a + 2}
end
end
#Each and push
x.report do
n.times do
result = []
arr.each do |a|
result.push(a + 2)
end
end
end
#Each and <<
x.report do
n.times do
result = []
arr.each do |a|
result << (a + 2)
end
end
end
end
和结果
user system total real
5.880000 0.080000 5.960000 ( 5.949504)
8.160000 0.010000 8.170000 ( 8.164736)
6.630000 0.010000 6.640000 ( 6.632686)
是运营商&#34;&lt;&lt;&#;比推方法更快?我没想到,我认为这是一种别名。
答案 1 :(得分:5)
each
应该比map
更快,因为前者不会修改/创建任何内容,而后者会这样做。但是在你的代码中,你正在比较不同的东西。 push
花费时间。您的代码与比较each
和map
无关。
答案 2 :(得分:3)
VALUE
rb_ary_each(VALUE array)
{
long i;
volatile VALUE ary = array;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
static VALUE
rb_ary_collect(VALUE ary)
{
long i;
VALUE collect;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
collect = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
}
return collect;
}
请注意,map
和each
几乎相同(这是预期的),但map
也需要创建一个数组,然后执行推送。您在Ruby中的each
版本基本上是做同样的事情,但是你的是Ruby,这是C,所以通过在较高级别重新创建较低级别会有额外的开销,并且C通常比Ruby更快反正。
答案 3 :(得分:1)
不确定,但具有指示性:
BufferStrategy
这是两种方法的不完美基准。询问matrix[n][n]
或require 'fruity'
def mapit(a)
a.map {|e| e + 2}.size
end
def eachit(a)
result = []
a.each do |e|
result.push(e + 2)
end.size
end
a = Array.new(1_000) { rand 10 }
compare do
map { mapit(a) }
each { eachit(a) }
end
#=> Running each test 32 times. Test will take about 1 second.
#=> map is faster than each by 2x ± 0.1
a = Array.new(10_000) { rand 10 }
compare do
map { mapit(a) }
each { eachit(a) }
end
#=> Running each test 4 times. Test will take about 1 second.
#=> map is faster than each by 50.0% ± 10.0%
a = Array.new(100_000) { rand 10 }
compare do
map { mapit(a) }
each { eachit(a) }
end
#=> Running each test once. Test will take about 1 second.
#=> map is faster than each by 2x ± 0.1
是否更快只适用于非常具体的比较。
答案 4 :(得分:0)
三年后我来了,因为我想回答OP在不同情况下提出的相同问题。很明显,如果使用map
和each
来创建新数组,则map
会更快,正如现有答案所解释的那样。
但是,在我看来,真正的问题是使用map
创建具有某些修改的新数组还是使用each
对现有数组进行相同的修改更快。为了对此进行测试,我修改了接受答案中的基准:
require "benchmark"
def mapmethod(input)
input.map(&:reverse)
end
def eachmethod(input)
input.map(&:reverse!)
end
n=10000
arr=Array.new(10000,'ab')
Benchmark.bm do |x|
#Map
x.report do
n.times do
mapmethod(arr)
end
end
#Each
x.report do
n.times do
eachmethod(arr)
end
end
end
我得到了这个结果:
user system total real
27.362799 0.103154 27.465953 ( 28.441034)
15.204973 0.392920 15.597893 ( 15.993965)
在我看来,这是一个非常有力的指标,表明修改现有阵列比创建具有相同修改的新阵列要快得多。因此,如果您不需要新的数组,我将使用each
,如果需要,我将使用map
。