我有一个包含+20000整数元素的数组。
我想创建一个新数组,其中旧数组中的每个元素都添加了一个修改号。在一个小样本数组上,它看起来像这样:
old_array = [2,5,6,8]
modifying_number = 3
new_array = [5,8,9,11]
有没有比这样的迭代更有效的方法?
class Array
def addition_by(x)
collect { |n| n + x }
end
end
答案 0 :(得分:3)
没有。 N
次迭代是此算法的最小复杂度。
您可以通过使用collect!
修改源数组来实现(如果由于某些原因不需要源数组)。复杂性将是相同的,不会创建额外的大对象。
答案 1 :(得分:3)
20k记录不用担心性能。
ary = Array.new(20000) { 1 }
ary.map! { |el| el + 1 }
完全没问题。
我建议修改初始数组而不是创建一个新数组(使用bang方法),所以肯定会使用更少的资源。
答案 2 :(得分:2)
我想这会意味着以另一种方式实施map
? This question处理此类任务。我已经在@JörgWMittag和@uishra中找到了答案的基准。虽然必须说speed
不是相关问题的要求,因此在这方面不能批评答案。我还在这个问题中加入了@ CarySwoveland的答案。
require 'fruity'
require 'matrix'
class Array
#jörg_w_mittag
def new_map
return enum_for(__callee__) unless block_given?
inject([]) {|acc, el| acc << yield(el) }
end
#uishra
def my_map(&block)
result = []
each do |element|
result << block.call(element)
end
result
end
#cary_swoveland
def vec_map(k)
(Vector[*[k]*self.size] + Vector[*self]).to_a
end
end
arr = (1..30000).to_a
k = 3
10.times do
compare do
core_map { ar = arr.dup; ar.map { |n| n + k } }
jörg_w_mittag { ar = arr.dup; ar.new_map { |n| n + k } }
uishra { ar = arr.dup; ar.my_map { |n| n + k } }
cary_swoveland { ar = arr.dup; ar.vec_map k }
end
puts
end
结果/输出摘要:
五次结果
#Running each test once. Test will take about 1 second.
#core_map is faster than jörg_w_mittag by 2x ± 1.0
#jörg_w_mittag is similar to uishra
#uishra is similar to cary_swoveland
两次结果
#Running each test once. Test will take about 1 second.
#core_map is faster than jörg_w_mittag by 2x ± 0.1
#jörg_w_mittag is similar to uishra
#uishra is similar to cary_swoveland
三次结果
#Running each test once. Test will take about 1 second.
#core_map is faster than uishra by 2x ± 1.0
#uishra is similar to jörg_w_mittag
#jörg_w_mittag is similar to cary_swoveland
答案 3 :(得分:1)
require 'matrix'
class Array
def vec_map(k)
(Vector[*[k]*self.size] + Vector[*self]).to_a
end
end
[1,2,3].vec_map 4
#=> [5, 6, 7]