benchmark

require 'benchmark'

total = (ENV['TOTAL'] || 1_000).to_i

strings = Dir["spec/**/*_spec.rb"]
floats = strings.map { |s| s.size.to_f + rand }

Benchmark.bmbm do |x|
  x.report("loop") do
    times = 0
    while times < total
      floats.each { |s| s }
      times += 1
    end
  end

  x.report("primitive") do
    times = 0
    while times < total
      floats.each { |s| s.special_add s }
      times += 1
    end
  end

  x.report("ffi s + s") do
    times = 0
    while times < total
      floats.each { |s| s + s }
      times += 1
    end
  end

  x.report("ffi P::F.add s, s") do
    times = 0
    while times < total
      floats.each { |s| Platform::Float.add s, s }
      times += 1
    end
  end

  x.report("ffi F.add s, s") do
    F = Platform::Float
    times = 0
    while times < total
      floats.each { |s| F.add s, s }
      times += 1
    end
  end
end

run

euler:rubinius brian$ rm ffi.rbc; TOTAL=10_000 shotgun/rubinius ffi.rb 
Rehearsal -----------------------------------------------------
loop                5.363105   0.000000   5.363105 (  5.363095)
primitive           7.478554   0.000000   7.478554 (  7.478548)
ffi s + s          28.856437   0.000000  28.856437 ( 28.856417)
ffi P::F.add s, s  10.915453   0.000000  10.915453 ( 10.915431)
ffi F.add s, s     10.432356   0.000000  10.432356 ( 10.432340)
------------------------------------------- total: 63.045905sec

                        user     system      total        real
loop                5.216899   0.000000   5.216899 (  5.216879)
primitive           8.549649   0.000000   8.549649 (  8.549653)
ffi s + s          28.714589   0.000000  28.714589 ( 28.714583)
ffi P::F.add s, s  10.994805   0.000000  10.994805 ( 10.994813)
ffi F.add s, s     10.541753   0.000000  10.541753 ( 10.541763)