在大阵列上进行加法的有效方法

时间:2016-09-22 10:24:49

标签: ruby

我有一个包含+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

4 个答案:

答案 0 :(得分:3)

没有。 N次迭代是此算法的最小复杂度。

您可以通过使用collect!修改源数组来实现(如果由于某些原因不需要源数组)。复杂性将是相同的,不会创建额外的大对象。

答案 1 :(得分:3)

20k记录不用担心性能。

ary = Array.new(20000) { 1 } 
ary.map! { |el| el + 1 }

完全没问题。

我建议修改初始数组而不是创建一个新数组(使用bang方法),所以肯定会使用更少的资源。

答案 2 :(得分:2)

我想这会意味着以另一种方式实施mapThis question处理此类任务。我已经在@JörgWMittag和@uishr​​a中找到了答案的基准。虽然必须说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]