我正尝试在 Ruby 中快速/高效地实现 Mandelbrot。很久很久以前,一种加快速度的方法是使用定点整数而不是 float 。
所以我做了以下基准测试,使用乘法或平方 ** 操作数将 float 和整数提升到平方数进行比较。
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 乘法几乎是 float 的两倍。
我有两个问题:
- 谁能解释一下?我可以想象的一个原因是 Fixnum 乘法比较慢,因为内部检查它是否需要转换为 Bignum。
- 其次,是否有 ruby 的快速整数乘法?
最佳答案
我想到了一些事情。您没有指定正在使用的 Ruby 实现。由于您在 Windows 上运行 Ruby 1.8.6,我假设您使用的是通过 Windows 一键安装程序安装的 MRI。
这是一种最坏的情况:
- MRI 是所有 Ruby 实现中最慢的
- Windows 上的 MRI 甚至比 Linux 或 OSX 上的 MRI 慢
- 一键安装程序使用来自 Ruby-Lang.Org 的预编译二进制文件,这些二进制文件是使用 1996 年的 Microsoft Visual C++ 6.0 编译的,因此比使用 Windows 编译的 MRI 甚至慢 Microsoft Visual C++ 10.0 或 GCC 4.x 甚至 GCC 3.x。
这里有一些您可以尝试提高性能的提示:
- 使用RubyInstaller项目,它使用用 GCC 3.x 而不是 MSVC6 编译的解释器,
- 也许自己重新编译解释器(使用 RubyInstaller 项目提供的 Rakefile 并不难),使用 GCC 4.x 和/或不同的优化选项(RubyInstaller 使用适度的优化选项编译,适用于通用 386 CPU),
- 使用比 1.8.6 更新的 MRI 版本,
使用不同的 Ruby 实现:
在后两种情况下,您可能需要稍微修改一下基准。两者最终都可以将 Ruby 代码编译为 native 机器代码,但这可能需要一段时间。例如,JRuby 在方法执行 20 次后编译为 JVM 字节码,HotSpot Server 在执行 20000 次后将 JVM 字节码编译为 native 机器码。此外,编译本身需要时间,因此程序需要运行一段时间才能通过提高性能来收回成本。
JRuby 的主要开发人员之一查尔斯·奥利弗·纳特 (Charles Oliver Nutter) 特别指出,根据工作负载,JRuby 可能需要 5-15 秒才能达到全速。您的基准测试速度大约快了 100 倍(这是您每天都不会听到的一句话......)。
关于ruby - ruby 中的快速/快速整数乘法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1791902/