InfoQ

News

Lessons from building Oracle Mix on JRuby on Rails

Posted by Werner Schuster on Nov 22, 2007 10:00 AM

Community
Ruby
Topics
Performance & Scalability ,
JRuby ,
Ruby on Rails
Tags
Ruby on Rails ,
Oracle ,
JRuby
Oracle Labs recently released Oracle Mix, a JRuby on Rails based social networking application. Rich Manalang now posted his experiences working on the project.  While the project is now running on JRuby, the initial work was done with MRI:
We built most of Mix using the standard Ruby interpreter (aka, MRI — Matz’ Ruby Interpreter) on Oracle DB XE using Ruby-OCI. Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.
As it turns out, the Rails plugin system proved to be very useful in making Mix work with Oracle's internal systems - in this case the Single Sign On (SSO) policy:
One critical part of the project was to support Oracle’s SSO policy. Meaning every web app that we deploy has to support SSO using the Oracle SSO service. It took me a few days to figure out how all this worked but once we did, it wasn’t difficult to plug it into the acts_as_authenticated Rails plugin that we were using.
With these issues out of the way, the team encountered another problem when deploying to JRuby on Rails: Performance:
After I had the boxes primed, we started doing early deploys on jRuby. The performance was terrible. About 20-40 reqs/sec on a single app server. Turns out that I didn’t have some of the production settings configured properly (i.e., not caching ruby classes, etc.) Once I modified a few environment settings (standard rails prod settings), I got about 80 reqs/sec on a single app server… better but not enough.
Long story short, after a flurry of investigations into the performance problems, performance figures improved:
Ola and the jRuby team found some interesting bottlenecks in the jRuby code. Within in a day or two, Ola and team had them patched up and we were beginning to see around 150-200 reqs/sec. After the app server warmed up, things got real interesting… the numbers went way up (400-600 reqs/sec).
This is only the beginning, as the post states, as these numbers are taken on a system that doesn't do any caching. So what caused the increase in performance? The JRuby team investigated a list of problems, discovering old problems such as regular expression performance:
But the discovery I made was when I looked at the performance of the regular expressions used in Rails. There are exactly 50 of them for each request, so I did a script that checked the performance of each of them against MRI. And I found that there was one in particular that had really interesting performance when comparing MRI to JRuby. In fact, it was between 200 and a 1000 times slower. What's worse, the performance wasn't linear.
This problem actually occurred in the each_line implementation of JRuby and not in the Rails code. With performance problems as this, and some others, discovered and fixed, JRuby speed in general improved considerably..

Next to bottlenecks in the JRuby implementation, some other reasons can slow down a JRuby application. Nick Sieger points out a few tricks JRuby users can do to improve the speed of their applications. The most important steps to take seem to be:
  • Switching off ObjectSpace.
    ObjectSpace is a feature that allows to iterate over all objects on the heap. Few libraries actually make use of this, so turning it off doesn't have consequences. JRuby 1.1, actually, turns this off by default. The increase in performance is considerable: because to provide the ObjectSpace functionality, every created object needs to be registered in a separate list structure, thus increasing costs for object creation.
  • Ensure the "server" VM is used
    The "server" VM can be used with a simple command switch, and ensures more aggressive performance optimizations.
  • Waiting for the JVM to warm up
    This is not really an optimization, but ensures that the right performance is measured. The way the JVM works, the bytecode is initially interpreted, and incrementally optimized and compiled to native code by a dynamic compiler. Only code that is actually used a lot is compiled and optimized, and this takes some time. This means, measuring performance, such as requests/second, on a freshly launched JVM will yield worse performance than on a JVM that has been running for some time.
  • Switching from a stable JRuby (like JRuby 1.0.x) to the development version
    This works particularly for JRuby 1.1 (the current development version), since this is the first JRuby with a complete JIT. However, since the development version can change quite a lot, this also means that using the latest version can mean newly introduced, unreported bugs. These can break an application in unexpected ways. Of course a proper test suite can help with keeping the effects of this low. Whether the overhead of keeping up with JRuby development is worth the extra performance must be decided on a case to case basis.

5 comments

Reply

JRuby and Performance by Geoffrey Wiseman Posted Nov 22, 2007 8:50 PM
Performance by Ola Bini Posted Nov 23, 2007 3:11 AM
Question by Alex Popescu Posted Nov 23, 2007 7:03 AM
Re: Question by d taye Posted Nov 23, 2007 4:19 PM
Re: Question by Rich Manalang Posted Nov 23, 2007 10:12 PM
  1. Back to top

    JRuby and Performance

    Nov 22, 2007 8:50 PM by Geoffrey Wiseman

    It's good to see JRuby performance picking up; in some of our early work with Ruby and JRuby, we hit a few performance snags, so I'm glad to see these improving before I have to face these again.

  2. Back to top

    Performance

    Nov 23, 2007 3:11 AM by Ola Bini

    Of course, the points you listed we have obviously done for Mix. ObjectSpace and -server made most of the largest jumps in numbers possible. It's on the application layer we haven't done much of any optimization.

  3. Back to top

    Question

    Nov 23, 2007 7:03 AM by Alex Popescu

    Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.


    Can somebody clarify the above statement? Is the statement made in terms of startup time, or something else?

    thanks,

    ./alex
    --
    .w( the_mindstorm )p.
    Alexandru Popescu
    Senior Software Eng.
    InfoQ Techlead/Co-founder

  4. Back to top

    Re: Question

    Nov 23, 2007 4:19 PM by d taye

    Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.

    Any attempts to run this on the tiered VM? I think 1.7 has that enabled by default nowadays.
    It would also be interesting to try this on IBM's 1.6 and (why not) BEA's 1.6. IBM has some sort of 'extended' support for class data sharing that includes app classes, and BEA still rocks on x86...

  5. Back to top

    Re: Question

    Nov 23, 2007 10:12 PM by Rich Manalang

    Yes, I was referring to the starting up jruby in general. When developing a rails app, you will have to make use of CLI tools like rake, script/console, etc... using those tools on JRuby is much slower than on MRI.

Exclusive Content

Ruby.rewrite(Ruby)

In this RubyFringe talk, Reginald Braithwaite writes Ruby code to read, write, and rewrite Ruby. Demos include extending Ruby with conditional expressions, call-by-name and more.

Book Except and Interview : Aptana RadRails, An IDE for Rails Development

Aptana RadRails: An IDE for Rails Development by Javier Ramírez discusses the latest Aptana RadRails IDE, a development environment for creating Ruby on Rails applications.

Fast Bytecodes for Funny Languages

Cliff Click discusses how to optimize generated bytecode for running on the JVM. Click analyzes and reports on several JVM languages and shows several places where they could increase performance.

Scott Ambler On Agile’s Present and Future

Scott Ambler, Practice Lead for Agile Development at IBM, speaks on the current status of the Agile community and practices having a look at the perspective of the Agile’s future.

Manager's Introduction to Test-Driven Development

Dave Nicolette and Karl Scotland try to introduce non-technical managers to one of the most popular Agile development techniques: Test-Driven Development (TDD).

Structured Event Streaming with Smooks

Smooks is best known for its transformation capabilities, but in this article Tom Fennelly describes how you can also use it for structured event streaming.

How to Work With Business Leaders to Manage Architectural Change

Successful architectures evolve over time to meet changing business requirements. Luke Hohmann presents how to collaborate with key members of your business to manage architectural changes.

Colors and the UI

In this article, Dr. Tobias Komischke explains how colors used in a GUI can influence our interaction with a computer and offers advice on using the appropriate colors for the interface.