Massive Ruby speed boost with JRuby and Java 7.
blog.jruby.org
blog.jruby.org
So I'm looking forward to the 0.7.5-release and with a bit of luck I might finally be able to jump on the jruby-bandwagon then.
Fwiw, I'm currently blocked on http://jira.codehaus.org/browse/JRUBY-6260
Apparently the fix is already done but hasn't made it into the 0.7.5dev gem yet.
There's probably mirrors of the JRuby downloads somewhere, eh? I don't know them offhand...
In other news, I realized our "org.jruby:jruby-dist" maven artifact hasn't been publishing a full dist tarball, like it's supposed to, so we'll get that fixed.
As an aside, I did run across a bug, not performance related, but a case around popen where JRuby doesn't behave the same as MRI - I raised a ticket (JRUBY-6225) but it doesn't seem to be getting any traction. I understand there are probably plenty of tickets to be prioritized, but this one is a bit of a show stopper for me. If anyone from the JRuby team is see this and has time to have a look at it I would be grateful.
Of course, we can always use help too :)
b) Now that Python is in a difficult transition to Python 3, a strong ruby is a game changing point. Antonio Cangiano `New Relic Holy Shmoly, Ruby 1.9 smokes Python away!` could be Jruby smokes Python away :) (if there is a two-fold increase in speed I expect A. Cangiano article rewrited)
c) What about duby and groovye?
I don't know the status of Groovy performance in general. I do know that on small numeric benchmarks, JRuby + invokedynamic beats fully-dynamic Groovy, but you can "cheat" and static-type some numeric logic in Groovy, which puts it out in front again.
A big IF? :-)
http://shootout.alioth.debian.org/u32/benchmark.php?test=all...
I believe MRI is generally faster than Python now when they're doing roughly equivalent work in Ruby and Python.
Specifically?
> I believe MRI is generally...
Show me the numbers ;-)
c) Groovy hasn't added any support for invokedynamic or even started on it. A month ago they announced they're removing their meta-object protocol rework from the upcoming version 2.0.
SpringSource seem to be repositioning Groovy as a staticly-typed language, this year adding primitive types like in Java. Before everything was an object, and primitives were regarded as leaky abstractions. 2 months ago they employed someone to write a static type checker called "Grumpy" for Groovy, and eventually type inference and optimization, but the work's just started so it might take quite some time depending on how good their new hire is. This year they also tried to rewrite the Antlr 2.7 based parser in Antlr 3.2, using a Google Summer of Code worker, but they didn't get very far. Perhaps the static type checking for Groovy will be more successful, perhaps not.
I imagine this repositioning was instigated by the Grails team wanting a faster language, with dynamicity an optional extra to be used only when required.
It also appears that the push toward more static typing in Groovy may come at the cost of dynamicity...or at least incompatible changes in Groovy's dynamic features. Perhaps it's the best move for them, though; they've always pushed Groovy's ability to run (and enhance) plain old Java code, but performance was considerably worse than Java.
It's unfortunate that other JVM dynamic languages did not start exploring invokedynamic sooner. It has been a complete game-changer for JRuby.
???
http://shootout.alioth.debian.org/u32/jruby.php
> Ruby 1.9 smokes Python away!
"I ran a recursive Fibonacci function..." Really.
JRuby already is as fast or faster than MRI, and a 3X increase in performance is absolutely huge.
A simple comparison using binary-tree (from computer language benchmark) between ruby1.9.1 and jruby show that on my machine jruby time is half of 1.9.1
~/lang/ruby/jruby-1.6.5/bin$ time ./jruby --server -J-Xmx2000m algo.rb 18 gives real 0m32.447s user 0m38.478s sys 0m0.904s
time ruby1.9.1 algo.rb 18 real 1m11.388s user 1m11.192s sys 0m0.148s
./jruby --server -J-Xmx2000m -v jruby 1.6.5 (ruby-1.8.7-p330) (2011-10-25 9dcd388) (OpenJDK 64-Bit Server VM 1.7.0_147-icedtea) [linux-amd64-java]
the algo.rb file is the version contributed by # contributed by Jesse Millikan # Modified by Wesley Moxam and Michael Klaus
this is n=18, for n=16,17 ... results are similar. Half the computing time.
Being able to write classes in Java (or Mirah) where speed is crucial, and use them from within JRuby without having to do any additional work, is a nice bonus as well.
The only downside is startup time, but that's been improving a lot recently.
Github:FI (the locally-installed version of Github) was, for instance, a JRuby application.
Here is how to get Oracle Java7 on Ubuntu:
wget http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz
tar -xvf jdk-7-linux-x64.tar.gz
sudo mkdir -p /usr/lib/jvm/
sudo mv jdk1.7.0/ /usr/lib/jvm/
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.7.0/jre/bin/java 0
sudo update-alternatives --config javaTo enable G1 on Java 7: -XX:+UseG1GC. Prepend -J if passing to the 'jruby' command.
MRI uses around 8MB
Edit: I get down voted for saying that I care about memory consumption? My use case may not be everyones, but it's a legitimate issue is it not?
JRuby largely uses more memory because we have a "real" garbage collector. The JVM, unlike MRI, allocates much more memory than the app needs. That gives it freedom to delay GC runs and push old objects into rarely-GCed sections of memory. It does also mean JRuby uses more memory on startup.
JRuby also has the JVM's subsystems booted and considerably more complex caching and optimization logic. This does increase the base size of a JRuby runtime.
It's possible to get JRuby to start in under 30MB if you explicitly force the JVM to use less memory with -J-Xmx30M or lower. But is it that big a deal? Let the JVM breathe, and your code runs better as a result.
I did set the Xmx and it still uses around 80MB. I'm not sure what in the world the JVM is doing there, but the permgen is another 20MB or so and then other native stuff, thread overhead, etc.
Is memory cheap? Yes and no. At work we have a rails site with two REST api backends both ruby. I also love RubyMine. Now here's my problem, I can't run all of those on the JVM on my macbook air. 4 gigs is not enough if I also have a browser open!
This is not a problem at all if I switch the apps to MRI and switch my editor to a non JVM based editor. I think the JVM people need to recognize this problem.
So, does this mean we can expect the same goodness for other dynamic JVM languages? Clojure maybe?
sudo update-java-alternatives
there is an error: no alternatives for -javaplugin.so
I don't want to lose my java applet for firefox,(ubuntu 11.04 64 bits,four-cores).
I would also like to see some comparison, for example like in the computer benchmark game between jruby and other ruby implementations.
What about clojure and scala? will they get a speed up with the new java 7 update? , Will it be three-fold like jruby (in certain cases?). Thanks for the great work on jruby. Being more dynamic is great!
I imagine the computer benchmarks game will update when we have a release of JRuby 1.7 out, sometime early 2012. If someone else wants to do some benchmark runs, I have no objection.
As for Clojure and Scala...they may see modest improvements from Java 7, but neither of them use invokedynamic at all. The biggest boost for JRuby comes from invokedynamic.
$ man update-java-alternatives
--jre
Limit the actions to alternatives belong to a runtime environment, not a development kit.
--jre-headless
Limit the actions to alternatives belong to the headless part of a runtime environment.
--plugin
Limit the actions to alternatives providing browser plugins. $ file .mozilla/plugins/libnpjp2.so
.mozilla/plugins/libnpjp2.so: symbolic link to
`/usr/local/lib/jvm/jre1.6.0_29/lib/amd64/libnpjp2.so'
There's one from OpenJDK as well. $ apt-cache show icedtea-plugin
Package: icedtea-plugin
Source: icedtea-web
Version: 1.1.4-1
Installed-Size: 276
Maintainer: OpenJDK Team <openjdk@lists.launchpad.net>
Architecture: amd64 $ update-java-alternatives --jre-headless
or $ update-java-alternatives --jre
this will not update the plugin-alternative which is not available (yet), see headius' comment => https://gist.github.com/1501186
(UPD: sorry, the following only applies to the standard OpenJDK7 on Ubuntu, not the u2 release )also on i386 and armel see https://bugs.launchpad.net/ubuntu/+source/openjdk-7/+bug/850...
workaround (change armel/arm to i386 if that's your arch):
$ cd /usr/lib/jvm/java-7-openjdk-armel/jre/lib/arm/
$ sudo ln -s jamvm/libjvm.so .https://bugs.launchpad.net/ubuntu/+source/openjdk-7/+bug/850...
I'd love to hear about people actually using EM on JRuby, if there's such folks out there.
"Compared to JRuby on Java 6, JRuby on Java 7 without invokedynamic is around 25% faster, and JRuby with invokedynamic is nearly 3 times faster."