使用Ruby NArray而不是Array有什么好处?

时间:2011-10-20 07:04:44

标签: ruby arrays numerical-computing narray

我刚刚遇到了Ruby的NArray库 - 请原谅我在提出这个问题时的无知:)

使用NArray库比标准Ruby Array实现有什么好处?

我已经看到NArray面向数值计算,但是看看API,看起来只有少数几个扩展,而不是数值 - 这是你无法用数组做的...... / p>

  1. 为什么不直接使用Array?
  2. 是否有巨大的速度优势?
  3. 是否有巨大的记忆优势?
  4. 使用常规Ruby Array类还有什么优势吗?
  5. 谷歌并没有真正想出这个问题的有用解释。

    我发现参考文献:

    http://rubydoc.info/gems/narray-ruby19/0.5.9.7/NArray

    http://narray.rubyforge.org/index.html.en

    http://raa.ruby-lang.org/project/narray/

3 个答案:

答案 0 :(得分:10)

另见关于NArray的幻灯片: http://www.slideshare.net/masa16tanaka/narray-and-scientific-computing-with-ruby

  

看起来像Array

只有几个扩展

不,它与Array完全不同。 NArray具有许多数值函数和多维特征。 另一方面,NArray是静态的;它没有推/弹方法等。 NArray的方法列表是http://narray.rubyforge.org/SPEC.en

  

_1。为什么不使用Array?

Array保存Ruby对象。保持数值是低效的。

  

_2。是否有巨大的速度优势?

是。上面幻灯片中的第36页显示NArray的速度提高了50倍。

请注意,如果循环是用Ruby编写的,则Array比NArray快。

  

_3。是否有巨大的记忆优势?

是。至于Float值,在我的64位Linux机器上,Array消耗的内存大约是NArray的4倍。

  

_4。使用常规Ruby Array类还有什么优点?

  • 支持多维数组
  • 支持数字函数
  • 无需对Array项目进行垃圾回收。 GC需要很长时间才能使用大型阵列。

答案 1 :(得分:4)

  

我已经看到NArray面向数值计算,但是看看API,看起来只有少数几个扩展,而不是数值 - 这是你无法用数组做的...... / p>

您遗漏了最重要的一点:NArray不仅仅是扩展进行数字处理,它也是限制。特别是

  • NArray个元素只能 是固定大小的整数或浮点数
  • NArray s本身也是固定大小的,它们无法缩小或增长

NArray的实施可以利用这些限制来提供卓越的性能。

答案 2 :(得分:1)

对于大型类型数组创建,NArray可以更快,但对于小型数组创建(例如对于临时中间对象),Ruby Array似乎速度更快。

基准代码:

require 'benchmark'

n1 = 1000000
n2 = 10000
Benchmark.bm do |x|
  x.report("NArray short float length 5:") { n1.times { NArray.sfloat(5) } }
  x.report("NArray long float length 5 :") { n1.times { NArray.float(5) } }
  x.report("NArray short int length 5  :") { n1.times { NArray.sint(5) } }
  x.report("NArray long int length 5   :") { n1.times { NArray.int(5) } }
  x.report("NArray object length 5     :") { n1.times { NArray.object(5) } }
  x.report("Ruby Array length 5        :") { n1.times { Array.new(5) } }  

  x.report("NArray short float length 10000:") { n2.times { NArray.sfloat(10000) } }
  x.report("NArray long float length 10000 :") { n2.times { NArray.float(10000) } }
  x.report("NArray short int length 10000  :") { n2.times { NArray.sint(10000) } }
  x.report("NArray long int length 10000   :") { n2.times { NArray.int(10000) } }
  x.report("NArray object length 10000     :") { n2.times { NArray.object(10000) } }
  x.report("Ruby Array length 10000        :") { n2.times { Array.new(10000) } }
end

结果:

                              user       system     total     real
NArray short float length 5:  0.740000   0.020000   0.760000 (  0.756466)
NArray long float length 5 :  0.770000   0.020000   0.790000 (  0.791446)
NArray short int length 5  :  0.750000   0.020000   0.770000 (  0.772591)
NArray long int length 5   :  0.760000   0.020000   0.780000 (  0.777375)
NArray object length 5     :  0.780000   0.020000   0.800000 (  0.801149)
Ruby Array length 5        :  0.450000   0.010000   0.460000 (  0.461501)    <====
NArray short float length 10000:  0.230000   0.050000   0.280000 (  0.281369)
NArray long float length 10000 :  0.430000   0.000000   0.430000 (  0.428917)
NArray short int length 10000  :  0.110000   0.010000   0.120000 (  0.113683)
NArray long int length 10000   :  0.230000   0.040000   0.270000 (  0.275942)
NArray object length 10000     :  0.460000   0.110000   0.570000 (  0.570558)
Ruby Array length 10000        :  0.440000   0.040000   0.480000 (  0.476690)