Technology and Software

Compile your own Ruby and use it with RVM

Prompted by the news about how gcc 4.9 makes Ruby 2.1 faster I decided to compile my own Ruby 2.2.0 and pit it against the one coming with rvm. I also want to keep switching between Rubies using RVM. I had to google a little to learn how to do it so I want to share.

rvm install 2.2.0
rvm use ruby-2.2.0
# find out the compilation options
ruby -r rbconfig -e 'puts RbConfig::CONFIG["configure_args"]'
 'optflags=-O2' '--enable-load-relative' '--sysconfdir=/etc'
 '--disable-install-doc' '--enable-shared'
wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.0.tar.gz
# important, always compare to the hash advertised at
# https://www.ruby-lang.org/en/downloads/
md5sum ruby-2.2.0.tar.gz
tar xzf ruby-2.2.0.tar.gz
cd ruby-2.2.0
mkdir -p /home/me/compiled-rubies/2.2.0p0
# configure with the same compilation options
# of the standard binary
CFLAGS=-O2 ./configure --enable-load-relative \
  --sysconfdir=/etc \
  --disable-install-doc --enable-shared \
  --prefix=/home/me/compiled-rubies/2.2.0p0
make
make test
make install
# make it available to rvm as ext-ruby-2.2.0-gcc4.9_O2
rvm mount /home/me/compiled-rubies/2.2.0p0 \
  -n ruby-2.2.0-gcc4.9_O2
rvm list
...
    ext-ruby-2.2.0-gcc4.9_O2 [ x86_64 ]
 => ruby-2.2.0 [ x86_64 ]
...
rvm use ext-ruby-2.2.0-gcc4.9_O2

The files in ~/.rvm/rubies/ext-ruby-2.2.0-gcc4.9_O2 will be symlinks to the ones in compiled-rubies/2.2.0p0 so don’t remove that directory.

The point of this post is already made but as a bonus here are the benchmarks of the two Rubies using Antonio Cangiano’s tests.

git clone git://github.com/acangiano/ruby-benchmark-suite.git
cd ruby-benchmark-suite
rvm use ruby-2.2.0 # for the standard one
rake
rvm use ext-ruby-2.2.0-gcc4.9_O2 # for the compiled one
rake # This might fail, see the note at the end

Here are the results: ruby-2.2.0 and ruby-2.2.0-gcc4.9_O2 (YAML), summary (CSV). TL;DR: the compiled Ruby is a little bit faster overall. It’s much faster in a few tests, a bit slower in some others. It’s a difficult choice and it probably depends on what you do.  Please notice all those tests that ended with errors (look at the YAML files). They could make a difference for the overall assessment of which version is faster but I didn’t dig into that issue yet.

In case of failure

Rake could end with a weird syntax error for the compiled Ruby. There are two possible fixes. One is to replace `which rake` with the version from the 2.2.0 binary distribution. The other is to really understand what’s going on. The key is: that rake is a bash script which execs a Ruby interpreter on itself using ruby’s -x switch which strips away the bash script at the beginning. But Ruby doesn’t seem to honour that. No time to investigate any further now…

Standard