我正在尝试在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乘法几乎是浮点数的两倍。
我有两个问题:
答案 0 :(得分:5)
有些事情会浮现在脑海中。您没有指定您正在使用的Ruby实现。由于您在Windows上运行Ruby 1.8.6,我将假设您使用通过Windows One-Click安装程序安装的MRI。
这是一种最糟糕的情况:
以下是您可以尝试提高效果的一些提示:
使用Ruby的不同实现:
在后两种情况下,您可能需要稍微修改基准。两者最终都可以将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)可以显着提高速度