Skip to content

Instantly share code, notes, and snippets.

@chrisseaton chrisseaton/mjit.md
Last active Feb 8, 2018

Embed
What would you like to do?

There's a better way to run that benchmark - using the benchmark-ips tool which is designed carefully to allow for optimising implementations of Ruby to do their work and will allow for the JIT to warm up.

require 'benchmark/ips'

def calculate(a, b, n = 40_000_000)
  i = 0
  c = 0
  while i < n
    a = a * 16807 % 2147483647
    b = b * 48271 % 2147483647

    c += 1 if (a & 0xffff) == (b & 0xffff)
    i += 1
  end
  c
end

Benchmark.ips do |x|
  x.iterations = 3
  
  x.report("calculate") do |times|
    calculate(65, 8921, 100_000)
  end
end

raise unless calculate(65, 8921) == 588
ruby 2.6.0dev (2018-02-07 trunk 62270) [x86_64-darwin17]
Warming up --------------------------------------
           calculate     9.000  i/100ms
           calculate     9.000  i/100ms
           calculate     9.000  i/100ms
Calculating -------------------------------------
           calculate    893.647  (±10.3%) i/s -      4.419k in   5.003980s
           calculate    872.846  (±12.7%) i/s -      4.275k in   5.000368s
           calculate    934.028  (±10.1%) i/s -      4.599k in   5.002686s

ruby 2.6.0dev (2018-02-07 trunk 62270) [x86_64-darwin17] (+JIT)
Warming up --------------------------------------
           calculate    10.000  i/100ms
           calculate    18.000  i/100ms
           calculate    18.000  i/100ms
Calculating -------------------------------------
           calculate      3.174k (± 9.9%) i/s -     15.552k in   4.999483s
           calculate      3.180k (± 8.2%) i/s -     15.786k in   5.002768s
           calculate      3.085k (±14.8%) i/s -     14.958k in   5.002559s

rubinius 3.84 (2.3.1 3970f17d 2017-08-02 4.0.1) [x86_64-darwin17.0.0]
Warming up --------------------------------------
           calculate     3.000  i/100ms
           calculate     3.000  i/100ms
           calculate     3.000  i/100ms
Calculating -------------------------------------
           calculate    114.830  (± 8.7%) i/s -    570.000 
           calculate    114.671  (± 9.6%) i/s -    570.000 
           calculate    118.078  (± 7.6%) i/s -    588.000 

jruby 9.1.13.0 (2.3.3) 2017-09-06 8e1c115 Java HotSpot(TM) 64-Bit Server VM 25.144-b01 on 1.8.0_144-b01 +jit [darwin-x86_64]
Warming up --------------------------------------
           calculate     9.000  i/100ms
           calculate    10.000  i/100ms
           calculate    10.000  i/100ms
Calculating -------------------------------------
           calculate      1.083k (±11.0%) i/s -      5.330k in   4.983511s
           calculate      1.097k (±11.8%) i/s -      5.400k in   4.995296s
           calculate      1.091k (±12.0%) i/s -      5.370k in   4.998160s

truffleruby 0.30.2, like ruby 2.3.5 <Java HotSpot(TM) 64-Bit Server VM 1.8.0_151-b12 with Graal> [darwin-x86_64]
Warming up --------------------------------------
           calculate   112.000  i/100ms
           calculate   157.000  i/100ms
           calculate   188.000  i/100ms
Calculating -------------------------------------
           calculate    352.284k (±15.6%) i/s -      1.646M in   4.979090s
           calculate    352.140k (±15.0%) i/s -      1.707M in   4.987553s
           calculate    360.077k (±13.6%) i/s -      1.755M in   4.988948s

Running that it looks like MJIT is over 3x faster! Which is very impressive and it's already doing better than both JRuby and Rubinius.

TruffleRuby is over 300x faster (I only mention it because it's my own implementation of a Ruby JIT), so there's still lots of rooms for optimisations, as the authors have already said themselves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.