JRuby - you've probably heard of it. But what is it? Is it something arcane? What are the implications of using it? Why are we having JRubyConf.EU?
Well, here's a short introduction, maybe it'll pique your interest :)
What is JRuby?
JRuby stands for "Just Ruby", because that's what it is, just another implementation of the Ruby language. Many people are scared of what the J could mean: Java. Some Rubyists even wonder if JRuby is even Ruby or maybe some other language. But I'm here to tell you, fear not! You don't have to write XML files or write
AbstractMetaSomethingFactoryImpls to get it to work. Try it out. Take a normal Ruby program, run it with JRuby, and you'll be on your way.
Who uses JRuby?
A spontaneous twitter poll by the JRuby team last November came up with the following companies using JRuby:
The number one reason why most companies use JRuby is probably performance. JRuby runs on the JVM (Java Virtual Machine) - think whatever you want about Java, but the JVM is a brilliant piece of software engineering. A lot of research went into the JVM in order to make it as effective as possible. Here's a few examples of how it accomplishes such an amazing feat:
- JIT (Just-in-time compilation) watches the code being run and notices if it's run repeatedly. If so, it optimizes that code and compiles it to machine code (super fast!) at run time.
- GC (Garbage Collection) - remember how excited we all were when generational GC landed in Ruby 2.1 and provided a huge speed boost? Well the JVM has had generational GC (and other cool stuff) for years.
It is also very telling that the ruby rogues episode about scaling rails basically turned into an episode about why you should use JRuby for performance and what's awesome about it. The podcast also includes details about the performance characteristics of JRuby: it can be terribly slow in the beginning. The JVM needs some time for the JIT to kick in and actually do the compilation. Steve mentions that after a new deploy, response times can be very slow (up to a second) for the first 30 to 45 seconds. But after ~5 minutes the JVM has worked its magic and response times are down to ~20 to 30 milliseconds!
That also explains why some people think that JRuby is slow: benchmarking only the first minute makes it appear that way. But for a proper benchmark you need to give JRuby (and rubinius) enough time to warm up. Keep in mind, the above mentioned times are for a full blown rails application - smaller applications and ruby scripts take less time to warm up.
Of course performance isn't the only highlight, here are some more for you:
- Parallelism: In JRuby, threads can actually be executed in parallel, unlike in CRuby. CRuby has the GIL (Global Interpreter Lock) which enforces that only one thread can run at the same time (like a huge mutex) - leaving your other cores idle and bored. Hence, parallelism has to be achieved through forking.
- Java integration: JRuby gives you easy access to the whole ecosystem of Java libraries, supplying you with libraries for almost anything you can imagine should you not find a Ruby library. It also allows interoperability with all other JVM based languages - such as Clojure, Scala and Groovy!
- Java tooling: Java and the JVM give you plenty of tools for profiling and monitoring, such as VisualVM
Why doesn't everyone use JRuby?
With all these advantages, why doesn't everyone use JRuby? There are many reasons for this, but I personally think that the biggest reason is that when people hear JRuby, they think of Java, which many Rubyists are not too fond of. Here is a short list of why people don't use JRuby along with some clarifications:
- memory usage - it is true that JRuby consumes more memory than CRuby. However, the way to scale CRuby apps is by forking, so that the memory consumption of your app is multiplied by the number of forks you make. With JRuby, you just make more threads. By doing this, memory consumption stays about the same and is therefore a lot lower than with CRuby when leveraging multiple cores. Charles Nutter explains it well in this presentation.
- C-extensions - JRuby can't run gems with C-extensions (it can run gems using C through ffi, though), which means you can't use some truly helpful gems. However, this doesn't occur too often, and substitutions exist which provide both C and Java-extensions (like nokogiri).
- performance - sometimes JRuby might appear to be slower than the alternatives, but in most cases that I'm aware of (and have benchmarked myself) it is faster when given enough time to warm up. But because various functions are often not run at all, or not enough, test runs can be slower, so you're not able to take advantage of JRuby's famous performance.
- catching up on features - JRuby has had to play catchup when it comes to implementing features that are already present in CRuby. But when JRuby 9k is released it will be compatible with Ruby 2.2 and will therefore be up to date :)
- startup time - even launching a small script takes a few seconds to start up under JRuby which makes common CLI usage a bit more tedious
If this post got you interested in JRuby, how to leverage it, reap the benefits, deal with limitations, deploy it, success stories... - consider joining us at JRubyConfEU (tickets available here). If that's not an option - go ahead and give JRuby a spin. Try 22.214.171.124 (currently in rc1) which is Ruby 2.2 compatible or try
1.7.21 which is Ruby 1.9 compatible (but can also be run in other compatibility modes like 1.8 and 2.0).
Remember, JRuby is just Ruby - enjoy all the rubies!