我制作了两个阵列,每个阵列有100万个项目:
a1 = 1_000_000.times.to_a
a2 = a1.clone
我试图将a2推入a1:
a1.push *a2
这回来了SystemStackError: stack level too deep.
但是,当我尝试使用时concat,我没有收到错误:
a1.concat a2
a1.length # => 2_000_000
我也没有得到splat运算符的错误:
a3 = [*a1, *a2]
a3.length # => 2_000_000
为什么会这样?我查看了文档Array#push,并用C语言编写.我怀疑它可能是在引擎盖下进行一些递归,这就是为什么它会导致大型数组的这个错误.它是否正确?push用于大型阵列不是一个好主意吗?
我想使用ruby ffi gem来调用ac函数,它有一个数组作为输入变量,输出是一个数组.也就是说,c函数看起来像:
double *my_function(double array[], int size)
我创建了ruby绑定:
module MyModule
  extend FFI::Library
  ffi_lib 'c'
  ffi_lib 'my_c_lib'
  attach_function :my_function, [:pointer, int], :pointer
我想用ruby代码打电话,如:
result_array = MyModule.my_function([4, 6, 4], 3)
我该怎么做?
虽然做了一些基准来回答这个约来连接阵列我感到惊讶的是,当我在使用JRuby也做了同样的基准测试是慢了很多的最快方法问题.
这是否意味着关于jRuby比MRI Ruby更快的旧的慢板已经消失了?或者这是关于如何在jRuby中处理数组?
这里的基准测试结果和MRI Ruby 2.3.0和jRuby 9.1.2.0两者都运行在64位Windows 7盒子上,所有4个处理器忙于50-60%,内存使用±5.5GB.必须使用参数启动jRuby -J-Xmx1500M以提供足够的堆空间.由于堆栈级别太深,我不得不使用push删除测试,并且还删除了最慢的方法,使测试时间不长.使用Jave运行时:1.7.0_21
require 'Benchmark'
N = 100
class Array
  def concat_all 
    self.reduce([], :+)
  end
end
# small arrays
a = (1..10).to_a
b = (11..20).to_a
c = (21..30).to_a
Benchmark.bm do |r|
  r.report('plus       ')  { N.times { a + b + c }}
  r.report('concat     ') { N.times { [].concat(a).concat(b).concat(c) }}
  r.report('splash     ') { N.times {[*a, *b, *c]} }
  r.report('concat_all ')  { N.times { [a, b, c].concat_all }}
  r.report('flat_map   ') { N.times {[a, …