views:

83

answers:

3

There is a very noticeable difference in application initiation time between running my specs from the command line with ruby 1.9.x vs. 1.8.7. My application initiates much faster with ruby 1.8.7 than with ruby 1.9.1 or 1.9.2. The application initiation difference is approximately 18 seconds. It takes about 5 seconds for my app to initialize with 1.8.7 and 23 seconds with 1.9.1 and 1.9.2.

Application initialization time is not a big deal for production, but it is a very big deal for BDD development. Every time I change my code and run my specs, I have to wait an additional 18 seconds per iteration.

I assume this application initialization time is attributed to YARV compiling bytecode as my application initializes.

Am I right about my YARV slowing down my application initialization, and is there a way to disable YARV on the command line. It would be very nice to be able to disable YARV only when I am running my specs.

+3  A: 

YARV is a pure Ruby compiler. If you disable it, there's nothing left.

More precisely: YARV is a multi-phase implementation, where each of the phases is single-mode. It consists of a Ruby-to-YARV compiler and a YARV interpreter. If you remove the compiler, the only thing you are left with is the YARV bytecode interpreter. Unless you want to start writing your app in YARV bytecode, that interpreter is not going to be of much use to you.

This is in contrast to mixed-mode implementations such as JRuby and IronRuby which implement multiple execution modes (in particular, both a compiler and an interpreter) within a single phase. If you turn off the compiler in JRuby or IronRuby, you are still left with a usable execution engine, because they both also contain an interpreter. In fact, JRuby actually started out as a pure interpreter and added the compiler later and IronRuby started out as pure compiler and they added an interpreter exactly because of the same problem that you are seeing: compiling unit tests is simply a waste of time.

The only interpreted implementation of Ruby 1.9 right now is JRuby. Of course, there you have the whole JVM overhead to deal with. The best thing you can do is try how fast you can get JRuby to start up (use the nightly 1.6.0.dev builds from http://CI.JRuby.Org/snapshots/ since both 1.9 support and startup time are heavily worked on right this very moment) using either some very fast starting desktop-oriented JVM like IBM J9 or try JRuby's Nailgun support, which keeps a JVM running in the background.

You could also try to get rid of RubyGems, which generally eats up quite a lot of startup time, especially on YARV. (Use the --disable-gem commandline option to truly get rid of it.)

Jörg W Mittag
Thank you for the great background information. I need RubyGems as my application is a Rails 3 application with many gem dependancies, but I think I will give JRuby a go as it does have 1.9 compatibility. Currently, my application requires 1.9.2 compatibility due to my dependencies, and I hope JRuby has 1.9.2 compatibility. If JRuby does not work out for me I will have to downgrade my code to be 1.8.7 compatible.
Sean McCleary
+3  A: 

There's currently no way to disable YARV, simply because MRI 1.9 only includes the virtual machine, and not an interpreter. Maintaining both would be way too much job for the core team.

In the future there will probably be ways to cache the bytecode YARV generates (like Rubinius does). At the moment there is no way to load such bytecode through Ruby (see #971), but you could easily write a C extension which accomplishes it.

However, I would say that 18 seconds is way too much and it's probably a bug. I know there are some threads at ruby-core which discusses the slowness of require; maybe you find something interesting there!

Magnus Holm
+1, I forgot about the `require` bugs.
Jörg W Mittag
Thank you for the advice. My application currently requires 1.9.2 due to dependencies. I would love to use Rubinius, but I do not believe that it supports 1.9.x compatibility. That is good to know about the require bug. I doubt I'd have the time to circumvent that issue.
Sean McCleary
A: 

the next RC of 1.9.2 out might be faster as it doesn't preload $: with all your gem lib dirs.

rogerdpack