将大型数组传递给类时是否会降低性能?

时间:2017-08-24 21:53:50

标签: ruby

我有一个处理大量ID的类。我需要它们在Initialize中,但只会在某些情况下使用它们。

实例化具有600万个ID的数组的对象比使用4个ID的数组实例化对象要慢吗? (在未使用此数据的情况下)

2 个答案:

答案 0 :(得分:5)

无论你的阵列有多大。 ruby中的变量是对象的引用。这意味着在两种情况下都会发送指针,但不会将实际数据作为参数发送。

require 'benchmark/ips'

class A
  def initialize(arr)
    @arr = arr
  end

  def mutate
    @arr[0] = 11 # once this code been launched, it will change original object.
  end
end

# Do not create test data in the bench!
big_one = 6_000_000.times.map { |_| rand(10)}
small_one = [1,2,3,4]

Benchmark.ips do |x|
  x.report do
    A.new(big_one)
  end

  x.report do
    A.new(small_one)
  end

  x.compare!
end 

所以,结果:

Warming up --------------------------------------
                       125.218k i/100ms
                       128.972k i/100ms
Calculating -------------------------------------
                          3.422M (± 0.7%) i/s -     17.155M in   5.014048s
                          3.485M (± 0.5%) i/s -     17.540M in   5.033405s

注意:你不能在基准测试中使用像#to_a这样的方法,(1..6_000_000)范围转换到数组是一个缓慢的操作,这会对最终得分产生影响。

答案 1 :(得分:0)

是的,这对性能不利。为了证明这一点,我创建了这个测试,在那里我创建了一个带有id的实例变量的类。然后我运行了一个简单的无关方法,为自己添加一个数字。

require 'benchmark/ips'

class TestSize
  def initialize(ids)
    @ids = ids
  end

  def simple_task(n)
    n + n
  end
end

Benchmark.ips do |x|
  x.report('4 ids') do
    test = TestSize.new((1..4).to_a)
    test.simple_task(3)
  end
  x.report('6 million') do
    test = TestSize.new((1..6_000_000).to_a)
    test.simple_task(3)
  end
  x.compare!
end

以下是结果

Warming up --------------------------------------
               4 ids   112.545k i/100ms
           6 million     1.000  i/100ms
Calculating -------------------------------------
               4 ids      1.557M (± 5.0%) i/s -      7.766M in   5.001166s
           6 million      5.947  (± 0.0%) i/s -     30.000  in   5.077560s

Comparison:
               4 ids:  1557013.9 i/s
           6 million:        5.9 i/s - 261822.49x  slower

所以你可以看到它慢得多,而且使用的内存要多得多。

我一直使用benchmark-ips来测试这样的想法。 https://github.com/evanphx/benchmark-ips

我正在运行OSX 10.12.6,ruby 2.4.1p111