From: Charles Oliver Nutter Date: 2007-11-06T00:41:27+09:00 Subject: Re: JRuby performance questions answered gga wrote: > Charles Oliver Nutter wrote: >> Many people believed we'd never be faster than the C implementation, and >> many still think we're slower. > > Isn't that still a correct impression and statement? Currently the C > implementation to benchmark against is 1.9, which is soon to become > the official release (early next year, if all goes to plan). 1.8 is > mostly 3 years-old code now or so. > Or is JRuby now faster than 1.9? Ruby 1.9 is not likely to be the standard, widely-used version of Ruby for some time. Matz estimated it probably wouldn't be the case until late 2008. He also mentioned at the conference that while 1.9.1 might be feature-stable, it's still a bit experimental and will probably not be a production-ready VM for a while. In my opinion, no, it's not really a direct comparison to put JRuby up against Ruby 1.9 because 1.9 contains several compatibility-breaking changes. Many of those changes enable faster performance at the cost of backward compatibility. JRuby is an implementation of Ruby 1.8, and under that definition, it's appropriate to compare it to other implementations of Ruby 1.8. Some example of compatibility-breaking changes in Ruby 1.9: - case/when with literals will be constant time, but not invoke === - Fixnum math will be performed as direct operations, rather than dispatch through Fixnum#+, Fixnum#-, and so on. - block arguments can only be local variables And so on. We plan to make all the same optimizations, but also make them individually configurable, so that if you want to have fast integer math but everything else 1.8 semantics, you'll be able to. Or if you want to turn on 1.9 features as a whole, you can. Since you ask, yes, there's a few benchmarks where we're already faster than 1.9: JRuby: 1m loops yielding three fixnums 10 times to block splatting and accessing them 3.225000 0.000000 3.225000 ( 3.225000) 3.189000 0.000000 3.189000 ( 3.189000) 3.170000 0.000000 3.170000 ( 3.170000) 3.152000 0.000000 3.152000 ( 3.151000) 3.322000 0.000000 3.322000 ( 3.322000) 1.9: 1m loops yielding three fixnums 10 times to block splatting and accessing them 4.940000 0.010000 4.950000 ( 4.973445) 4.950000 0.020000 4.970000 ( 4.971358) 4.950000 0.010000 4.960000 ( 4.984771) 4.950000 0.010000 4.960000 ( 4.980683) 4.950000 0.010000 4.960000 ( 4.973008) ~/NetBeansProjects/jruby $ jruby -J-server test/bench/bench_fib_iterative.rb 11.610000 0.000000 11.610000 ( 11.611000) 11.481000 0.000000 11.481000 ( 11.481000) ~/NetBeansProjects/jruby $ ../ruby1.9/ruby -I ../ruby1.9/lib test/bench/bench_fib_iterative.rb 13.110000 4.700000 17.810000 ( 17.928527) 12.930000 4.770000 17.700000 ( 17.818631) 1.9's eval performance is also considerably degraded due to the cost of compilation...in some cases even slower than Ruby 1.8. >> Now that I've set that record straight, any questions? >> > > I do have one, yes. How much work does the JRuby team place in > actually improving Sun's JVM? > > Recently there was a question of actually turning off ObjectSpace for > JRuby as a default, instead of actually taking the JVM and enhancing > it to support some sort of ObjectSpace, which seemed more like the > right answer to me. The problems with ObjectSpace are not just problems you can flip a switch and make go away; they're systemic issues that will affect any modern GC. Look at it this way: In Ruby, where Objects do not move around in memory, it's easy to just walk through the entire set of objects in memory and return them in turn. There's no parallel threads to create more garbage, and there's no concurrent garbage collector moving objects around and compacting the heap. On the JVM, however, it's an entirely different situation. Not only are threads actually running in parallel, creating their own garbage...the GC itself runs in parallel on many versions of Java; so you'd not only have to stop all other threads from running, you'd have to stop the garbage collector itself. The other answer here is that...you already can do these things; they're used for profiling and debugging modes of the JVM. And oddly enough, the most common applications of ObjectSpace.each_object are for runtime profiling and debugging. The difference in the JVM (and in JRuby 1.1) is that we're not going to saddle users with the performance hit of what's typically a profiling/debugging feature that they'll never use on a production server. (and of course we're very keen on improving the JVM...but there's only so many hours in a day) - Charlie