ruby中的快速/快速整数乘法?

时间:2009-11-24 18:12:31

标签: ruby multiplication mandelbrot

我正在尝试在Ruby中快速/高效地实现Mandelbrot。很久以前,加速它的一种方法是使用定点整数而不是浮点数。

所以我做了以下基准测试,使用乘法或平方**操作数将浮点数和整数提升比较为平方。

require 'benchmark'

Benchmark.bmbm(10) do |x|  
  x.report("float-multip") do
    for z in 0..100000 
      zf = z.to_f
      y = zf*zf
    end
  end  

  x.report("float-square") do
    for z in 0..100000 
      zf = z.to_f
      y = zf**2
    end
  end  

  x.report("int-multip") do
    zo = 0
    for zi in 0..100000 
      y2 = zo*zo
      zo += 1
    end
  end   

  x.report("int-multip") do
    for zi in 0..100000 
      y2 = zi**2
    end
  end  
end

,这将生成以下输出:

Rehearsal ------------------------------------------------
float-multip   0.125000   0.000000   0.125000 (  0.125000)
float-square   0.125000   0.000000   0.125000 (  0.125000)
int-multip     0.250000   0.000000   0.250000 (  0.250000)
int-multip     0.282000   0.000000   0.282000 (  0.282000)
--------------------------------------- total: 0.782000sec

                   user     system      total        real
float-multip   0.110000   0.000000   0.110000 (  0.110000)
float-square   0.125000   0.000000   0.125000 (  0.125000)
int-multip     0.219000   0.016000   0.235000 (  0.235000)
int-multip     0.265000   0.015000   0.280000 (  0.282000)

清楚地表明Fixnum乘法几乎是浮点数的两倍。

我有两个问题:

  • 任何人都可以解释一下吗?我能想象的一个原因是Fixnum乘法因为内部检查是否需要转换为Bignum而变慢。
  • 其次是ruby的快速整数乘法?

4 个答案:

答案 0 :(得分:5)

有些事情会浮现在脑海中。您没有指定您正在使用的Ruby实现。由于您在Windows上运行Ruby 1.8.6,我将假设您使用通过Windows One-Click安装程序安装的MRI。

这是一种最糟糕的情况:

  1. MRI是所有Ruby实现中最慢的
  2. Windows上的MRI 甚至比Linux或OSX上的MRI更慢
  3. One-Click安装程序使用Ruby-Lang.Org中的预编译二进制文件,这些二进制文件是从1996年使用Microsoft Visual C ++ 6.0编译的,因此在编译的Windows上比使用MRI时的甚至更慢 Microsoft Visual C ++ 10.0或GCC 4.x甚至GCC 3.x。
  4. 以下是您可以尝试提高效果的一些提示:

    • 使用RubyInstaller项目,该项目使用使用GCC 3.x而不是MSVC6编译的解释器,
    • 也许自己重新编译解释器(使用RubyInstaller项目提供的Rakefiles并不是很难)使用GCC 4.x和/或不同的优化选项(RubyInstaller使用适度优化选项和通用386 CPU编译),
    • 使用比1.8.6更新的MRI版本,
    • 使用Ruby的不同实现:

      • YARV明显快于MRI(不幸的是,它只实现了Ruby 1.9,因此您可能需要更改代码),
      • 在很多情况下,
      • JRuby明显快于YARV,它实现了Ruby 1.8和Ruby 1.9(它还有一个-fast命令行选项,它与Ruby略有不兼容,但是改进了性能,包括算术性能)和
      • IronRuby也可能比YARV更快,具体取决于工作量。

    在后两种情况下,您可能需要稍微修改基准。两者最终都可以将Ruby代码编译为本机机器代码,但可能需要一段时间。例如,JRuby在方法执行20次后编译为JVM字节码,HotSpot Server在执行20000次后将JVM字节码编译为本机机器码。此外,编译本身需要时间,因此程序需要运行一段时间才能通过提高性能来获得成本。

    特别是JRuby首席开发人员之一Charles Oliver Nutter表示,根据工作量的不同,JRuby可能需要5-15秒才能提升到全速。你的基准测试速度大约是100倍(这是你每天都听不到的句子......)。

答案 1 :(得分:3)

1.8.6在这方面要慢一些。 1.8.7做得更好,1.9.1做得更好。我不知道为什么,但是rvm同意你和Pavel认为1.8.6很慢。

1.8.6: 
Rehearsal ------------------------------------------------
float-multip   0.140000   0.000000   0.140000 (  0.141560)
float-square   0.150000   0.000000   0.150000 (  0.146286)
int-multip     0.220000   0.000000   0.220000 (  0.223255)
int-multip     0.180000   0.000000   0.180000 (  0.183850)
--------------------------------------- total: 0.690000sec

1.8.7:
Rehearsal ------------------------------------------------
float-multip   0.090000   0.000000   0.090000 (  0.092346)
float-square   0.080000   0.000000   0.080000 (  0.080335)
int-multip     0.070000   0.000000   0.070000 (  0.068012)
int-multip     0.080000   0.000000   0.080000 (  0.081713)
--------------------------------------- total: 0.320000sec

1.9.1:
Rehearsal ------------------------------------------------
float-multip   0.070000   0.000000   0.070000 (  0.065532)
float-square   0.080000   0.000000   0.080000 (  0.081620)
int-multip     0.060000   0.000000   0.060000 (  0.065371)
int-multip     0.070000   0.000000   0.070000 (  0.065761)
--------------------------------------- total: 0.280000sec

答案 2 :(得分:0)

我无法解释你的表格。但我可以解释一下(ruby 1.8.7):

                   user     system      total        real
float-multip   0.600000   0.000000   0.600000 (  0.612311)
float-square   0.650000   0.000000   0.650000 (  0.649399)
int-multip     0.450000   0.010000   0.460000 (  0.457004)
int-multip     0.690000   0.000000   0.690000 (  0.692879)

糟糕。整数乘法胜过浮点乘法。

由于您的处理器比我的处理器慢5倍(我在基准测试中增加了十倍的重复次数),因此必须有一些不关注红宝石的处理器。

**操作可能使用了浮点运算(exp(x * ln(2)),因此它与其他浮点运算一样慢。

答案 3 :(得分:0)

jruby可能有更快的算术(或1.9.x)也用C语言(例如:http://segment7.net/projects/ruby/inline_optimization.html)可以显着提高速度