Fast / fast integer multiplication in ruby?

I am trying to make a quick / efficient implementation of Mandelbrot in Ruby. Once upon a time, one way to speed it up was to use fixed-point integers instead of floating ones.

So, I did the following comparative test, comparing casting a float and integer to a square using the multiplication operand or square **.

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

and this generates the following output:

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)

which clearly shows that Fixnum multiplication is almost twice as slow as floating point.

I have two questions:

  • Can anyone explain this? The reason I can imagine is that Fixnum multiplication is slower due to an internal check to see if it needs to be converted to Bignum.
  • Secondly, is there a quick multiplication for ruby?
+5
4

1.8.6 . 1.8.7 , 1.9.1 . , , rvm , 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
+3

. , Ruby . Ruby 1.8.6 Windows, , MRI, Windows One-Click.

:

  • MRI Ruby.
  • MRI Windows , MRI Linux OSX
  • Ruby-Lang.Org, Microsoft Visual ++ 6.0 1996 , , , MRI Windows, Microsoft Visual ++ 10.0 GCC 4.x GCC 3.x.

, :

  • RubyInstaller, , GCC 3.x MSVC6,
  • , ( Rakefiles, RubyInstaller) GCC 4.x / (RubyInstaller 386 ),
  • , 1.8.6,
  • Ruby:

    • YARV , MRI ( , Ruby 1.9, , , ),
    • JRuby , YARV , Ruby 1.8, Ruby 1.9 ( a -fast , Ruby, , )
    • IronRuby , YARV, .

. Ruby- , . , JRuby - JVM , 20 , HotSpot Server - JVM , 20000 . , , , .

, , JRuby, , JRuby 5-15 , . 100 ( ...).

+5

. ( 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)), , .

0

All Articles