Rails 3.1 and installing Ruby 1.9.2-p290 with the ‘fast require’ patch, readline, iconv

When Rails 3 was released, many users noticed that Ruby 1.9.2 and Ruby-head (basically 1.9.3) seemed to be awfully slower when loading Rails 3 apps, than Ruby 1.8.7. Then, back in May, Xavier Shay posted an article to his blog with some interesting findings: he noticed that the way later versions of Ruby require files and keep track of the files that have already been loaded isn’t very efficient, causing Rails 3 apps (which require thousands files at startup) to load a lot more slowly. He also released an awesome patch for Ruby 1.9.3, that did seem to improve the loading times and make them more comparable to those of Ruby 1.8.7, so other patches were then released for Ruby 1.9.2 as well (I suggest you read his post for more details; you can also find more information if you Google for ‘Ruby 1.9 fast require patch’).

Over the past few months, I have been sticking to a patched version of Ruby 1.9.2-p180, without upgrading to the latest stable revision (p290) since I couldn’t find yet a version of the ‘fast require’ patch that would work correctly with this revision as well. Yesterday, however, I started working a new Rails 3.1 app, and it seemed that the p180 revision wasn’t working well with the latest release of Rails. I am not sure of whether this had something to do with the particular configuration of my system (I tried reinstalling RVM and Ruby a few times though), but I would get warning and errors mainly related to Sass like

...(cut)...
... warning: already initialized constant ROOT_DIR
... warning: already initialized constant RUBY_VERSION
... warning: already initialized constant RUBY_ENGINE
... warning: already initialized constant ENCODINGS_TO_CHECK
... warning: already initialized constant CHARSET_REGEXPS
... warning: already initialized constant PARENT
...(cut)...

and

...
script/rails:6:in `require'
script/rails:6:in `<main>'
error scss [not found]

when, for example, bootstrapping the administration of some model with a quick and dirty scaffolding.

I didn’t want to spend much time investigating this, so also out of curiosity I tried to install an updated version of Ruby to see if it would help – and in fact it did, so I was lucky. After trying a few patches for the ‘fast require’, I eventually found one that actually worked with p290, so here’s how you’d use it to install and patch the latest stable revision of Ruby 1.9.2, with RVM:

curl https://raw.github.com/gist/1008945/4edd1e1dcc1f0db52d4816843a9d1e6b60661122/ruby-1.9.2p290.patch > /tmp/192.patch
rvm uninstall 1.9.2 && rvm cleanup all && rvm fetch 1.9.2
rvm install 1.9.2 --patch /tmp/192.patch

In my case, I also needed to install some dependencies such as iconv and readline, since I like using bond to achieve bash-like auto completion in my IRB/Rails consoles.

At first, I tried to install the relevant packages with RVM:

rvm pkg install iconv
rvm pkg install readline
rvm uninstall 1.9.2 && rvm cleanup all && rvm fetch 1.9.2
rvm install 1.9.2 --patch /tmp/192.patch --with-readline-dir=$rvm_usr_path --with-iconv-dir=$rvm_usr_path

but this would blow up when also applying the ‘fast require’ patch:

...
ruby-1.9.2-p290 - #fetching
ruby-1.9.2-p290 - #extracted to /Users/vito/.rvm/src/ruby-1.9.2-p290 (already extracted)
Applying patch '/tmp/192.patch' (located at //tmp/192.patch)
ERROR: Error running 'patch -F25 -p1 -f <"//tmp/192.patch"', please read /Users/vito/.rvm/log/ruby-1.9.2-p290/patch.apply.192.patch.log
...
ERROR: There has been an error while running configure. Halting the installation.

I believe this was due to the fact that RVM also needs to apply a second patch to Ruby, in order to install readline, if readline is being installed with RVM. I am not sure of how to apply more than one patch at the same time (unless I am missing something, I don’t think this is possible?); I also got weird errors related to iconv (for example required by the json gem), when trying to start an app or to execute a rake task:

/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:98: warning: already initialized constant NaN
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:100: warning: already initialized constant Infinity
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:102: warning: already initialized constant MinusInfinity
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:121: warning: already initialized constant UnparserError
rake aborted!
no such file to load -- iconv
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:358:in `require'
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json/common.rb:358
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json.rb:1:in `require'
/Users/vito/.rvm/gems/ree-1.8.7-2011.03/gems/json-1.5.1/lib/json.rb:1
...(cut)...

Ruby 1.9.x already includes some equivalent of the iconv gem by default, so I am not sure of what triggered this error. I even tried to install the iconv gem anyway, without much success (‘failed to build native extensions’ for some reason).

I found a workaround by installing both readline and iconv with Homebrew instead:

brew install readline
brew install libiconv
brew link libiconv

rvm cleanup all && rvm fetch 1.9.2
rvm install 1.9.2 --patch /tmp/192.patch --with-readline-dir=/usr/local/Cellar/readline/6.2.1 --with-iconv-dir=/usr/local/Cellar/libiconv/1.14

Note that I also had to run brew link libiconv due to some other error. This is now working as expected, and I can definitely see the speedier startup with my Rails 3 apps, while the aforementioned dependencies also work. If you install the patch, it’s simple to compare the startup time before and after the patch. Here’s an example with one application I’m working on:

before

time rails runner 'a=1'

real 0m21.427s
user 0m17.585s
sys 0m2.004s

after

time rails runner 'a=1'

real 0m14.725s
user 0m12.721s
sys 0m1.996s

As you can see, in this case the patch cut several seconds from the startup time, although it also depends a lot on the application and on how large it is.

The shorter startup time can make a nice difference especially when you are running tests (unless you’re using something like spork, that is), so if you haven’t patched your Ruby install yet, for whatever reason, I’d definitely recommend you to.

Rest in peace, Steve

I would like to salute a man whose vision, creativity and achievements have indeed contributed for decades to improving our lives. A genius whose incredible eye and passion for great design and user experience will live forever and be source of inspiration for many generations to come.

After a long battle with pancreatic cancer lasted several years, Apple’s legendary co-founder and former CEO Steve Jobs died today at 56. It’s a very sad day not only for all technology enthusiasts, but for everybody.

He’s been a most inspiring person not only through the amazing products he’s delivered; his life-business experience has been remarkable: he co-founded Apple from nothing, bringing the company to wild success in just a few years; when his vision diverged from that of the board he got fired from the very company he had co-founded, “in a very public way” as he himself remembered years later; yet, he didn’t give up: he went on to founding NeXT and build some of the technologies that would later become part of the core of the Mac OS operating system; when a then struggling Apple acquired NeXT, he became Apple CEO again and over the years that followed he managed to bring the company back to life and transform it into the most valuable company in the world, in what has been often referred to as “the greatest second act in the history of business”. And at the same time, he made of Pixar the best animation studio around, delivering some of the most amazing animation movies ever made.

Apple have updated their home page to show a tribute to Jobs:

apple-home-steve-jobs-png-1c6b9a

The picture links to a page dedicated to him:

apple-site-steve-jobs-png-1c6b9a

“Apple has lost a visionary and creative genius, and the world has lost an amazing human being. Those of us who have been fortunate enough to know and work with Steve have lost a dear friend and an inspiring mentor. Steve leaves behind a company that only he could have built, and his spirit will forever be the foundation of Apple. If you would like to share your thoughts, memories, and condolences, please email rememberingsteve@apple.com.”

Apple’s new CEO Tim Cook also sent a note to all Apple employees:

“Team,
I have some very sad news to share with all of you. Steve passed away earlier today.
Apple has lost a visionary and creative genius, and the world has lost an amazing human being. Those of us who have been fortunate enough to know and work with Steve have lost a dear friend and an inspiring mentor. Steve leaves behind a company that only >he could have built, and his spirit will forever be the foundation of Apple.
We are planning a celebration of Steve’s extraordinary life for Apple employees that will take place soon. If you would like to share your thoughts, memories and condolences >in the interim, you can simply email rememberingsteve@apple.com.
No words can adequately express our sadness at Steve’s death or our gratitude for the opportunity to work with him. We will honor his memory by dedicating ourselves to >continuing the work he loved so much.
Tim””

It seems like Wikipedia’s page dedicated to Jobs has already been updated too:

“Steven Paul Jobs (February 24, 1955 – October 5, 2011) was an American computer entrepreneur and inventor. He was co-founder, chairman, and chief executive officer of Apple Inc. Jobs also previously served as chief executive of Pixar Animation Studios; he became a member of the board of directors of The Walt Disney Company in 2006, following the acquisition of Pixar by Disney. He was credited in Toy Story (1995) as an executive producer.”

Needless to say, messages about Jobs’ death are now trending on Twitter, and most blogs and news sites are reporting the news.

I would like to remember Steve Jobs with a quote on innovation, since I find his words most inspiring in my work:

“Innovation is not about saying yes to everything. It’s about saying no to all but the most crucial features.”

And also with his unforgettable commencement speech at Stanford University in 2005.

Thank you and rest in peace Steve, I’ll dearly miss your genius, your products, your exciting keynotes and your “one more thing”!