JRuby vs Ruby: why would you ever use ruby?

Ruby 1.9 has a "giant lock" that prevents threads from running in parallel. So even though they're native, you'd still need 16 processes to utilize 16 cores fully. The only implementations to support actual parallel-executing threads are JRuby, IronRuby, and MacRuby. Of these, only IronRuby and JRuby run Rails. Of these, only JRuby is production- ready and fast.

Ruby 1.9 *may* also suffer from issues common to other GIL-based systems like Python (giant interpreter lock), since you start to have the OS scheduler and the GIL scheduler fighting each other. Here's a good presentation on the issues in Python:

http://blip.tv/file/2232410/

- Charlie

Makes sense, not sure why I didn't remember that (especially when I directly ran into this with a somewhat toyish app that does alot of CPU intensive work in threaded batches). Thanks.

I use both MRI and JRuby -- often at the same time in the same project when developing.

One advantage I didn't see in the thread so for MRI is that the interpreter starts fast. This is great when starting lots of small tasks from the console.

Here's a couple of pluses for JRuby that I haven't seen mentioned:

1) It is very easy to make multiple, complete, and isolated Ruby installation using JRuby. I know there are some tools to make this easier in MRI -- I even wrote a simple one -- but this is trivial in JRuby.

2) For some rendering operations in development mode JRuby can be 20x faster.

This is a strange result -- in general I've found JRuby to be about twice as fast as MRI in production ... but I'd never seen this result before ...

I've got a complex Rails application for authoring secondary science investigations and one of the render tasks generates a composite xml document that represents all of the objects in an investigation. Right now the largest investigation is about 350k rendered into xml and represents over 1100 objects. Roughly that corresponds to about 1100 partial calls.

I have not done ANY work on improving performance in the rendering speed yet (lots of partials calling partials) and noticed that the render speed when running in MRI in development mode has gotten very long as authors have finally started making real investigations.

I put together a benchmark measuring the time to render 11 investigations in xml.

The JRuby results were quite impressive:

           Development Production

Sorry, I still can’t understand how to run rails in thread safe mode under JRuby (one running instance supporting multiple concurrent requests).

If I try to enable config.threadsafe! in config/environments/production.rb under Glassfish Gem my Rails application still run single threaded.

Here a very simple example (environment is: glassfish gem v. 0.9.5 / jruby 1.3.1 / rails 2.3.3 / ubuntu 9.04 / notebook centrino dual core / 2gb Ram):

rails concurrent

cd concurrent

script/generate controller test test

edit app/controllers/test_controller.rb, modify source as follow:

class TestController < ApplicationController

def test

@value = Time.now

sleep 10

end

end

edit app/views/test/test.html.erb, modify source as follow:

<%= @value %>

edit config/environments/production.rb, uncomment last line as follow:

config.threadsafe!

edit config/environemt.rbm uncomment frameworks line as follow (no database, resource, mail support for this very simple

test…):

config.frameworks -= [ :active_record, :active_resource, :action_mailer ]

Now run:

jruby -S gfrake config

edit config/glassfish.yml, modify config as follow (notice 4 runtime instances !):

environment: production

jruby-runtime-pool:

initial: 4

min: 4

max: 4

And finally start glassfish gem:

jruby -S glassfish

Now, if you try to call 4 times (concurrently) the following url…

…you must wait 40 seconds for the 4th response… This is a wrong behaviour because trying the same test under phusion passenger I wait only 10 seconds for the 4th response (in fact passenger start up 4 rails processes, 1 for each concurrent request)… I want to know if is it possible to run Rails with only one running instance supporting multiple concurrent requests… Many thanks in advance…

I believe for Jruby the min and max runtimes need to bet set to 1 for this to happen and work with config.threadsafe!

AD

Many thanks for the suggestion, but the problem is still here…

My runtime configuration now is:

tex@tex-laptop:~xxx$ jruby -S glassfish

Parsing config file: /home/tex/xxx/config/glassfish.yml

Arguments:

runtimes=>1

runtimes_min=>1

runtimes_max=>1

contextroot=>/

environment=>production

app_dir=>/home/tex/xxx

port=>3000

pid=>

log=>/home/tex/xxx/log/production.log

log_console=>false

log_level=>7

daemon=>false

jvm_options=>

domain_dir=>/home/tex/xxx/tmp/.glassfish

Starting GlassFish server at: 127.0.0.1:3000 in production environment…

Writing log messages to: /home/tex/xxx/log/production.log.

Press Ctrl+C to stop.

The problem is always the same: 40 seconds for the 4th response…

I think I’m the only one on the heart that cannot run rails with JRuby with multiple concurrent requests, all the other out there seems that can run it without any problem (maybe I’m unlucky, sigh…)

I think this is your mistake. You told Rails to run in threadsafe mode, which Glassfish gem will pick up; but then you forced Glassfish to run with a runtime pool of 4 instances. If you *don't* do this it works fine, and your four concurrent requests all take the same amount of time (10s) to run because they're running in parallel.

The only bottleneck you might run into with this contrived example is that GF by default only has a certain size thread pool, and will start to park requests until one of the request-processing threads is available, but you can crank that up too if needed.

I assure you, Rails on JRuby runs great in threadsafe mode, with only a single runtime. You can crank thousands of requests through a single instance, something impossible to do with any other Ruby implementation so far.

- Charlie

Dear All,

I think Ruby and JRuby both have their advantages. It depends on the environment which one is easier to integrate and maintain. In a typical Linux-Apache-(Postgres|MySQL)-Ruby environment JRuby with its additional requirement of Java comes with some painful extra cost, which can otherwise be avoided. In an java-enviroment, where part of the stuff should be done with Ruby+Rails it might be the other way round.

My own observation is that JRuby is slightly faster than Ruby 1.8.7, but Ruby 1.9 is way faster than that. But it depends on what Java you use, what you do etc..

I would like to point out that the set of libraries available may be quite different. Many Ruby-libraries use native c-code and are unavailable in JRuby.

Another point is that operating-system-functionality is not really available in Java beyond what can be commonly implemented on different platforms supported by Java. So they are not easily accessed in JRuby either. If such stuff is needed, native Ruby is better. I have even used native Ruby to add Windows- and Linux-specific functionalities for accessing OS-features needed and hidden in Java from a Java software.

So I would really recommend to carefully consider which one is better.

Best regards,

Karl

I would worry about changes to the Java language that would affect JRuby. Ruby implementation is never going to be a big concern of the Java devs, nor should it be.

Dear All,

I think Ruby and JRuby both have their advantages. It depends on the environment which one is easier to integrate and maintain. In a typical Linux-Apache-(Postgres|MySQL)-Ruby environment JRuby with its additional requirement of Java comes with some painful extra cost, which can otherwise be avoided. In an java-enviroment, where part of the stuff should be done with Ruby+Rails it might be the other way round.

I think the "cost" of the Java dependency is extremely low. Debian, Suse, Redhat, Ubuntu...all the Linux distributions how have single- command installs for Java that "just work". Pick a "Java 6" or "Java 1.6" version and you're ready to go. I would dare say it's at least as easy as Ruby, and probably easier on peculiar systems that have Java installs but no supported Ruby install.

It is for this reason JRuby has become the Ruby of choice for a lot of people on Windows; install Java, unpack JRuby, and you're done.

My own observation is that JRuby is slightly faster than Ruby 1.8.7, but Ruby 1.9 is way faster than that. But it depends on what Java you use, what you do etc..

Java 6+ should always be used for comparison, and if you're benchmarking or running a production server you should pass --server to JRuby to use the optimizing JVM. We're generally about on par with 1.9...faster at some things and slower at others.

I would like to point out that the set of libraries available may be quite different. Many Ruby-libraries use native c-code and are unavailable in JRuby.

Almost all libraries that require C code have equivalents in Java that can be called directly from Ruby. In many cases, we've even ported the C code or wrapped those libraries so that the gem versions will work (like, Hpricot, Mongrel, etc). Many C libraries can also be called directly from JRuby with FFI. In general, you probably have access to *more* libraries from JRuby because you've got Ruby libs, Java libs, and any C libs you can call with FFI.

Another point is that operating-system-functionality is not really available in Java beyond what can be commonly implemented on different platforms supported by Java. So they are not easily accessed in JRuby either. If such stuff is needed, native Ruby is better. I have even used native Ruby to add Windows- and Linux-specific functionalities for accessing OS-features needed and hidden in Java from a Java software.

We've done a lot of work to implement OS functionality that doesn't normally exist in Java (and isn't planned for addition). Things like FFI for programmatically calling C libraries, POSIX filesystem functions, UNIX sockets, and more. We've worked very hard to make as much OS-level code work well on JRuby as possible.

- Charlie

Changes to the Java languages are extremely unlikely to be anything but helpful for JRuby. There are also JVM-level features planned for Java 7 which could help JRuby tremendously. I would not worry at all about Java changes negatively impacting JRuby, and I should know.

- Charlie

Hej,

I have no doubt that JRuby is good stuff and I actually use it myself.

My own RubyForge-procect (long-decimal) is done in such a way that it work both in Ruby 1.x and JRuby.

Best regards,

Karl