Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JRuby Performance

Tags:

I have a Rails 3.2.2 application that I am looking to run using JRuby 1.6.7 (1.9.2 mode).

I have a sample app running in MRI ruby 1.9.3 and a typical request is returning in ~40ms: Completed 200 OK in 36ms (Views: 27.5ms | ActiveRecord: 8.2ms)

Under JRuby using the same request is anywhere from 3 to 20 times slower depending on the page. For the same operation as above it takes ~180ms: Completed 200 OK in 180ms (Views: 153.0ms | ActiveRecord: 24.0ms)

Is this a normal performance difference? I have read that JRuby is roughly equal on speed with MRI. The results hold on my Mac and a Windows server (where unfortunately it will need to run). Packaging it up with Warbler running under Tomcat is just as slow.

The above times are from a basic rails app created for testing the JRuby. On the more complex app the times are even farther apart. On that app there is more ruby code being run on some pages. It seems that the more the page is ruby dependent the greater the performance difference I am observing. I have done no tuning of JRuby, since I don't know quite where to start.

So my questions are: is this normal? What can I do to tune JRuby?

like image 651
Larry Gebhardt Avatar asked Apr 20 '12 19:04

Larry Gebhardt


People also ask

What is the difference between Ruby and JRuby?

JRuby is similar to the standard Ruby interpreter except written in Java. JRuby features some of the same concepts, including object-oriented programming, and dynamic typing as Ruby. The key difference is that JRuby is tightly integrated with Java, and can be called directly from Java programs.

What is the use of JRuby?

JRuby is an open source implementation of the Ruby programming language for the Java Virtual Machine (JVM). It allows Ruby applications to be run within a Java Virtual Machine and interface with libraries written in either Java or Ruby.

Does JRuby need Java?

x, JRuby internally needs to require 'java' so it has already required 'java' by the time your expression is evaluated. So technically it is true that "require 'java'" loads Java interoperability, but since our kernel does this now it is largely a no-op by the time you call it (see return value of the require).

What is truffle Ruby?

TruffleRuby is a high-performance implementation of the Ruby programming language built on GraalVM using the Truffle language implementation framework and the GraalVM compiler. TruffleRuby is one part of GraalVM, a platform for high-performance polyglot programming.


1 Answers

Is this a normal performance difference?
I have read that JRuby is roughly equal on speed with MRI.

No, that's not normal. Once the JVM has warmed up, Rails requests under JRuby are usually significantly more performant than under MRI, both in terms of raw execution speed and garbage collection.

It sounds like your app is misconfigured. The first thing to check is the configuration of Rails itself - please ensure that Rails is not in development mode, and that config.threadsafe! is enabled in your production environment. Threadsafe mode will result in there being only one shared copy of Rails loaded into memory when your app is running.

Also check that your database configuration is taking advantage of connection pooling, e.g. pool: 20 in database.yml.

Finally, check your JVM and JRuby settings – both are highly tunable. You need to ensure that there is enough memory allocated to the JVM upon startup, and then enough memory for normal smooth operation of your application; otherwise the JVM will constantly be forced to prematurely and frequently garbage collect, which will significantly degrade performance.

For example some of the settings for a modestly specced VPS might be something like:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

... but don't copy these settings blindly! You will have to experiment and work out what is good for you with respect to the memory resources that are available on your server.

That said, whilst JRuby will probably consume less memory than the total sum of multiple Rails processes under MRI, you will definitely need to allocate a little more up front for a single JVM process. Be generous to JRuby, and JRuby will reward you for your kindness :-)

You can read more about tuning JRuby and the JVM here: https://github.com/jruby/jruby/wiki/PerformanceTuning

Update

You do not need to set config.threadsafe! in Rails 4.0 and above; it is threadsafe by default.

like image 74
Scott Avatar answered Sep 19 '22 14:09

Scott