The Great Ruby Shootout (July 2010)

The Great Ruby Shootout measures the performance of several Ruby implementations by testing them against a series of synthetic benchmarks. Recently I ran Mac and Windows shootouts as well, which tested a handful of implementations. However this article reports on the results of extensive benchmark testing of eight different Ruby implementations on Linux.

The setup

For this shootout I included a subset of the Ruby Benchmark Suite. I opted to primarily exclude tests that were executed in fractions of a second in most VMs, focusing instead of more substantial benchmarks (several of which came from the Computer Language Benchmarks Game). The best times and least memory allocations out of five runs are reported here for each benchmark.

All tests were run on Ubuntu 10.4 LTS x86_64, on an Intel Core 2 Quad Q6600 2.40 GHz, 8 GB DDR2 RAM, with two 500 GB 7200 rpm disks.

8 implementations

The implementations tested were:

  • Ruby 1.8.7 p299
  • Ruby 1.9.1 p378
  • Ruby 1.9.2 RC2
  • IronRuby 1.0 (Mono 2.4.4)
  • JRuby 1.5.1 (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20)
  • MagLev (rev 23832)
  • Ruby Enterprise Edition 2010.02
  • Rubinius 1.0.1

JRuby was run with the –fast and –server optimization flags.

Disclaimer

Synthetic benchmarks cannot predict how fast your programs will be when dealing with a particular implementation. They provide an (entertaining) educated guess, but you shouldn’t draw overly definitive conclusions from them. The values reported here should be assumed to be characteristic of server-side — and long running — processes; they should be taken with a grain of salt.

Time Results

Please find below the execution times for the selected tests. Timeouts indicate that the execution of a single iteration for a given test took more than 300 seconds and had to be interrupted. Bold, green values indicate the best performer out of each test.

Warning: The bm_primes.rb benchmark was originally written to aid the development of the Prime class. As such in 1.9.2 it was rewritten in C, which makes it a poor representation of implementation performance. This benchmark will removed in the future.

Time Table on Linux

If you are not interested in the individual test results, the information presented in the table above is summarized directly below:


  Ruby 1.9.2         JRuby          
Min.   : 0.013   Min.   : 0.382 
1st Qu.: 3.258   1st Qu.: 3.051
Median : 4.543   Median : 4.997
Mean   : 9.262   Mean   : 9.180
3rd Qu.: 8.573   3rd Qu.: 8.969
Max.   :45.009   Max.   :48.850

    MagLev         Ruby 1.9.1   
Min.   : 0.351   Min.   : 0.015
1st Qu.: 2.140   1st Qu.: 3.387
Median : 6.069   Median : 6.205
Mean   : 9.100   Mean   :10.860
3rd Qu.: 9.266   3rd Qu.:11.559
Max.   :51.221   Max.   :46.849

 Ruby 1.8.7         IronRuby     
Min.   : 0.708   Min.   :  3.601
1st Qu.: 5.102   1st Qu.: 10.505
Median : 8.380   Median : 12.912
Mean   :18.785   Mean   : 26.539
3rd Qu.:24.793   3rd Qu.: 36.115
Max.   :75.653   Max.   :135.204
  
   Rubinius           REE       
Min.   : 0.484   Min.   : 0.584
1st Qu.: 3.087   1st Qu.: 4.343
Median : 9.636   Median : 6.660
Mean   :13.232   Mean   :15.036
3rd Qu.:17.674   3rd Qu.:21.336
Max.   :73.050   Max.   :61.960

For the sake of convenience, I also produced a box plot from the successful data points:

Box plot of times

There are a few considerations based on these results that I feel are worth mentioning:

  • As you can see Ruby 1.9, JRuby and MagLev converge towards a similar performance level according to these tests.
  • Ruby 1.9.2 manages to squeeze in a bit of extra speed when compared to Ruby 1.9.1 (which is a welcome improvement).
  • Ruby 1.9 seems to be either much faster than Ruby 1.8 or roughly as fast, depending on the test. This appears to be in line with what I’ve seen in real world programs. There are programs that will only receive a 10-20% boost from 1.9, while others improve drastically. The results really depends on what a program spends its time doing.
  • Performance wise, Rubinius is really starting to be a much more serious contender.
  • Ruby Enterprise Edition is slightly faster than Ruby 1.8.7, to the extent where this is clearly visible in almost all of the tests.
  • IronRuby running on Mono was the worse of the lot.

Memory Results

The following table shows the approximate memory consumption for each implementation when running each benchmark:

Memory allocation on Linux

Summarized:


  Ruby 1.9.2        Ruby 1.9.1          
Min.   :  4.320   Min.   :  4.580     
1st Qu.:  4.378   1st Qu.:  4.695     
Median :  6.285   Median :  6.920     
Mean   : 20.795   Mean   : 15.669     
3rd Qu.: 10.162   3rd Qu.: 11.383     
Max.   :171.500   Max.   :100.570
 
   Ruby 1.8            REE     
Min.   :  3.040   Min.   :  8.220
1st Qu.:  4.290   1st Qu.:  9.682
Median :  7.745   Median : 15.565
Mean   : 20.698   Mean   : 27.014
3rd Qu.: 11.273   3rd Qu.: 38.620
Max.   :103.520   Max.   :125.910

  Rubinius           MagLev       
Min.   : 37.63   Min.   : 81.74   
1st Qu.: 39.78   1st Qu.: 82.52   
Median : 45.48   Median : 83.53   
Mean   : 65.70   Mean   : 96.29   
3rd Qu.: 58.22   3rd Qu.: 98.10   
Max.   :215.33   Max.   :175.85   
 
    JRuby       
Min.   : 49.04  
1st Qu.: 71.23  
Median :176.72  
Mean   :169.41  
3rd Qu.:209.04  
Max.   :404.06

And finally, in graph form:

Memory Box Plot

A few considerations on memory:

  • Memory readings for IronRuby were not available, so they were not included.
  • Ruby 1.9.2 uses the least amount of memory (as one might expect).
  • JRuby was by far the most memory intensive of the group.
  • Ruby Enterprise Edition used less memory than 1.8.7 in a few tests, but overall was more memory hungry than 1.8.7. This is really odd and entirely unexpected.

Linux Vs. Windows

This shootout and the Windows one were both performed on the same machine, thus we can compare how the same implementation perform under different operating systems. The only adjustment that’s required is the timeout. Every result longer than 60 seconds from this shootout needs to be considered a timeout, because the previous shootout did so as well.

It is commonly believed that Ruby performs much better on Linux than on Windows (with the exception of IronRuby). Let’s find out if these test results confirm that notion.

Ruby 1.8.7:

Ruby 1.8.7 on Linux and Windows

Ruby 1.9.2:

Ruby 1.9.2 on Linux and Windows

JRuby:

JRuby on Linux and Windows

Finally, in chart form (yellow entries are on Windows as indicated by the labels containing W):

Ruby on Linux Vs. Windows

To use a beloved MythBusters expression, this myth is confirmed.

Note: As requested by a few commenters, here is a comparison of IronRuby as well (.NET 4.0 Vs. Mono 2.4.4):

Ruby 1.8.7 on Linux and Windows

Conclusion

In conclusion, let me just state that it’s nice to see several implementations getting faster. Ruby 1.9.2, JRuby, MagLev and Rubinius are all becoming serious competitors and working their respective ways closer to a similar performance level. If you think these benchmark shootouts are becoming boring, then the results are becoming more stable and predictable. I suspect that as time goes on, performance will not be the real distinguishing factor when choosing a Ruby implementation, other features will be.

Get more stuff like this

Subscribe to my mailing list to receive similar updates about programming.

Thank you for subscribing. Please check your email to confirm your subscription.

Something went wrong.

34 Comments

  1. Brian Cardarella July 19, 2010
  2. Monty Williams July 19, 2010
    • Antonio Cangiano July 19, 2010
  3. Aaron July 19, 2010
  4. Monty Williams July 19, 2010
  5. Burke Libbey July 19, 2010
  6. Isaac Gouy July 19, 2010
  7. Hongli Lai July 19, 2010
  8. Dave Duchene July 19, 2010
  9. Orion Edwards July 19, 2010
    • Antonio Cangiano July 19, 2010
      • Ryan Riley July 25, 2010
  10. Orion Edwards July 19, 2010
  11. Keith Pitty July 19, 2010
  12. raggi July 19, 2010
  13. Simon July 21, 2010
  14. Simon July 21, 2010
  15. roger July 30, 2010
  16. roger July 30, 2010
  17. Miguel de Icaza July 30, 2010
  18. my22301 August 1, 2010
  19. roger August 2, 2010
  20. Isaac Gouy August 19, 2010
    • Antonio Cangiano August 19, 2010
      • Isaac Gouy August 19, 2010
      • Isaac Gouy August 19, 2010
  21. Cristian M?gheru?an-Stanciu May 17, 2012
  22. Finity October 10, 2012
  23. kiz November 17, 2012

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.