Ruby Weekly is a weekly newsletter covering the latest Ruby and Rails news.

How To Get That Edge Ruby Faster-Loading-Hotness in Ruby 1.9.2 Now

By Peter Cooper / June 8, 2011

A few days ago I told the story of ruby-head (MRI) getting 36% faster loading, perfect for tackling those file-heavy Rails 3 apps. Awesome for Ruby 1.9.3 but not so good for us now, right? Todd Fisher to the rescue! He's created a patch backporting the performance tweak to Ruby 1.9.2-p180.

Tip: If you're still on 1.8, check out The Ruby 1.9 Walkthrough, a mega screencast aimed at Ruby 1.8.7 developers who want to learn all about what's new, what's gone, and what's different in Ruby 1.9.2 and 1.9.3.

First, The Results

As the current production version of Ruby, a boost for Ruby 1.9.2-p180 should benefit most of you so I knew I had to share Todd's work as soon as I'd given it a test run. I ran the same benchmarks as in my earlier post and got a reduction in Rails 3 app load time of:

  • 16.7% for the empty Rails 3 app
  • 23.6% for the 'larger' in-production Rails 3 app

Only ~20% faster compared to ruby-head's 35%? That's actually good news! It means ruby-head (and so, hopefully, 1.9.3) has some extra performance boosts beyond the loading stuff - awesome! (Bear in mind in the previous post I benchmarked ruby-head with the patch against normal 1.9.2-p180.)

Now, The How

So how do you get this stuff? First, you need to be using RVM to manage your Ruby installs. You'll need to figure things out for yourself if you're compiling Ruby by hand. If you're using other forms of package management, you might find this all a bit 'hacky' and want to give it a miss.

Obligatory disclaimer: Don't do this unless you have a basic idea of what you're doing. And if your performance isn't improved, don't blame us. Boring bit over.

OK RVM users, do this:

curl https://raw.github.com/gist/1008945/7532898172cd9f03b4c0d0db145bc2440dcbb2f6/load.patch > /tmp/load.patch
rvm get head   # always good to make sure you're up to date with RVM
rvm reload
rvm install ruby-1.9.2-p180 --patch /tmp/load.patch -n patched
rvm use ruby-1.9.2-p180-patched

Note: You can just use ruby-1.9.2-patched but I'm playing it safe in the example ;-)

Note 2: Someone has reported that the above has resulted in an error at the patching stage. I've run it on two machines now without any problems but if you have problems, look at the log file RVM tells you to check out. It might give you a hint. Feel free to post a comment on this post too.

And now you're on the 'patched' Ruby 1.9.2. You'll need to run bundle again in your project(s) but in theory everything should work as before, just with faster loading.

So Todd Fisher just made your Rails 3 app start up somewhere around 20% faster without making you move away from a reliable, production version of Ruby. Buy the guy a beer when you see him next.

[ad] RailsKits is here to bring you great ready-made Rails code for you to use in your projects. More than just plugins, these starter kits can act as the foundation of your new Rails application. You can save hours of time, skipping the boring stuff and diving right into the code that makes your application different from all the rest.

Comments

  1. Charles Feduke says:

    Pretty impressive. I got this to work with no issues and there's a noticeable speed improvement on my MBP. I have guard/spork/growl running; previously when I saved a spec I'd have a couple seconds of wait time for the growl notification to appear. Now it seems like its nearly instant.

  2. Dr Nic Williams says:

    I'm getting the errors installing the patch as Mike in this gist - https://gist.github.com/53031fcff0f3258f0f90#comments

  3. Jacques Crocker says:

    It installed ok, however my project is now throwing Psych errors: https://gist.github.com/1013931

    Really hoping ruby team supports an officially supported 1.9.2-p181 with this patch. It probably would speed up Heroku dyno boot times quite a bit

  4. Mix says:

    I've tried it and it works... but it's way too slower than 1.8.7.

    1.8.7:
    Finished in 0.2067 seconds
    21 examples, 0 failures, 3 pending

    real 0m7.510s
    user 0m4.940s
    sys 0m2.430s

    1.9.2:
    Finished in 0.66704 seconds
    21 examples, 0 failures, 3 pending

    real 0m31.116s
    user 0m28.450s
    sys 0m2.160s

    1.9.2-patched:
    Finished in 0.39284 seconds
    21 examples, 0 failures, 3 pending

    real 0m17.468s
    user 0m15.310s
    sys 0m1.940s

    And it's just a very simple app of 40-50 loc with some gems

    Doing bdd with autotest it's just frustrating using 1.9.2, it takes too much time to run the test :(

  5. Joel Moss says:

    Got mine patched and running. Not a huge difference, but my spec suite ran in 5.93 secs before, and it now runs in 5.6 secs. Better than before I suppose.

    Cheers!

  6. Kevin Menard says:

    Nice to see this backported. However, there's no evidence here that the performance gap between this and head is due to additional performance boosts in head. Perhaps the patch has different runtime characteristics in 1.9.2 and head (it was written for head after all). Or perhaps head was more heavily affected by the issue and thus the patch had a much larger influence. I'm just reluctant to say "there's a difference and it must be because head is faster!"

  7. Peter Cooper says:

    Joel: Surprised you didn't see better on a small suite (the one for my larger app doesn't get a massive boost but it's 2 minutes long so a few seconds on loading is nothing). Guessing you don't have many entries in the Gemfile but quite a few unit tests? (So less loading to improve.)

  8. Peter Cooper says:

    @Jacques: The problem might be related to the site hosting the YAML library being down last night so RVM was skipping it on the install. Was a common problem with RVM users last night :-(

  9. Cody Russell says:

    It's failing to compile in load.c for me:

    gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -\
    Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long -fno-common -pipe -I. -I.ext\
    /include/x86_64-darwin10.7.0 -I./include -I. -DRUBY_EXPORT -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE \
    -o load.o -c load.c
    load.c: In function ‘get_loaded_features_hash’:
    load.c:99: error: ‘rb_vm_t’ has no member named ‘loaded_features_hash’
    load.c:102: error: ‘rb_vm_t’ has no member named ‘loaded_features_hash’
    load.c: In function ‘get_filename_expansion_hash’:
    load.c:112: error: ‘rb_vm_t’ has no member named ‘filename_expansion_hash’
    load.c:115: error: ‘rb_vm_t’ has no member named ‘filename_expansion_hash’
    load.c: In function ‘rb_feature_p’:
    load.c:292: error: ‘loadable_ext’ undeclared (first use in this function)
    load.c:292: error: (Each undeclared identifier is reported only once
    load.c:292: error: for each function it appears in.)
    load.c: In function ‘Init_load’:
    load.c:773: error: ‘j’ undeclared (first use in this function)
    make: *** [load.o] Error 1

  10. Cody Russell says:

    My bad. It turns out I was getting the same error DrNic was, and the solution (however strange it is) was to rm the patch, rm ~/.rvm/archives/ruby-1.9.2-p180*, rm ~/.rvm/src/ruby-1.9.2-p180*, then re-fetch the patch and restart the build.

  11. Shane Mingins says:

    Did the install as outlined with no issues. Just running spec suite to compare gave me this:

    => ruby-1.9.2-p0 [ x86_64 ]
    Finished in 260.15 seconds
    1762 examples, 0 failures, 22 pending

    => ruby-1.9.2-p180-patched [ x86_64 ]
    Finished in 273.49 seconds
    1762 examples, 0 failures, 22 pending

  12. Tadas says:

    Pretty impressive!
    1.9.2-p136 :20.32s user 3.54s system 81% cpu 29.322 total
    1.9.2-p180-patched: 9.96s user 3.48s system 70% cpu 19.003 total
    Although not enough to say good-bye to spork.

  13. Matt Royal says:

    If you are unable to install the patched ruby and the error log contains messages about failed hunks, then you may be able to fix the problem by running "rvm cleanup all" before you install the patched Ruby.

    If you're having issues with Psych, you can edit your config/environment.rb file in Rails and add this line:

    YAML::ENGINE.yamler = 'syck'

    The problem is likely that Ruby is using Psych for YAML parsing, and the 1.9.2 version of Psych can't handle merge keys (eg. <<: *default)

  14. Stefan Kaes says:

    You might also consider using the railsexpress patchset for 1.9.2 (https://github.com/skaes/rvm-patchsets).

    It also contains 1.9.2 versions of my GC patches (which are contained in REE).

  15. Zlaj says:

    Thanks Matt Royal! "rvm cleanup all" did the trick for me.

  16. Joe Van Dyk says:

    For me, the patch dropped loading the Rails environment from 18.5 seconds to 12.5 seconds.

    I WANT MORE! :)

  17. Jan De Poorter says:

    This crashes for me on ttfunk, especially on the following line:

    Hash[*(0..255).zip(0..255).flatten]

    When trying it out it seems the culprit is the Range#zip(Range)

    The full crash log:
    https://gist.github.com/1018547

  18. Regis d'Aubarede says:

    Sory, not a comment, it's only to signal this article to
    your attention :
    http://chris.wailes.name/?page_id=97

    by

  19. Kirill Maximov says:

    Tried it with my 2.3.x project - got ~23% performance improvement on project startup. Good work, thanks!

  20. Kirill Maximov says:

    Interesing, but patches from Stefan Kaes gave me better performance improvement (again, on 2.3.x project):

    Start with plain 1.9.2-180: 8.3sec
    Start with plain 1.9.2-180-patched: 6.4sec
    Start with plain 1.9.2-180-railsexpress: 5.9sec

    So, Stefan's patch for ruby 1.9.2 gave me ~29% startup time increase!

  21. Leena says:

    I've tried this on an medium sized rails3 app and could see atleast 20-30% improvement for rails server and rake tasks

  22. Jarosław Skrzypek says:

    Seems this is really important issue :-) I have also investigated it some time ago and finally wrote a blog post with patch about it. I measured up to 40% improvement on load time, while entire patch changes only four lines.
    Here are the details: http://www.lunarlogicpolska.com/blog/2011/06/14/tracing-processes-for-fun-and-profit.html

  23. Marcin Kulik says:

    @Jarosław: I hope your patch will get merged upstream. It got me biiig improvement - I don't need spork b/c specs now start so much faster.

  24. Kenn Ejima says:

    Our Rails app has 49 gems, and with that patch, the loading time has been shortened from 51.830s to 23.269s. Really impressive.

    I really hope this one will get backported to 1.9.2.

Other Posts to Enjoy

Twitter Mentions