Using XRuby to Speed up Ruby Script Performance

Wed, Oct 1, 2008 (Programming)

Do you want to squeeze the most performance out of your Ruby scripts? If so, you might be interested in a little project called XRuby.

According to the website “in most benchmark tests, XRuby runs faster than Ruby 1.8.5″. Personally, I was a bit skeptical, and you may be too. So let’s explore this lofty claim further and see if we really can achieve better performance for my highly <snicker> complex Ruby scripts.

First, let me address what you are thinking… Does it run Rails apps? At the moment, no, but it has made great strides and will hopefully achieve that goal sometime in the future. Currently it is able to pass all tests found in the samples folder of the standard 1.8.5 installation. That’s pretty impressive. Now, I want to validate that performance claim. Here is the procedure to set up XRuby and run a Ruby-turned-Java example.

This article operates under the assumption that Java 6 SE has been installed. If you are running Ubuntu and don’t yet have Java 6 run the following command:

codenomad@sparta:~/$ sudo apt-get install sun-java6-jdk

Now, grab a copy of XRuby over at http://code.google.com/p/xruby/ and then do the following in your directory of choice. (My home folder is the default directory where the zipped file is located, and the current release is xruby-0.3.3a).

codenomad@sparta:~$ mkdir xruby
codenomad@sparta:~$ cd xruby/
codenomad@sparta:~$ unzip ../xruby-0.3.3a-src.zip

[smartads]

On to the build process.

Before you can build XRuby, you need to set the environment variable JAVA_HOME to your JVM installation and give the build script execute permissions.

For Ubuntu, there is a symbolic link that points to the latest Java installation under /usr/lib/jvm. Below is how you would set that variable and build XRuby.

TIP: Ubuntu does provide a command line utility to switch your Java implementation quickly called ‘update-alternatives‘ This utility can be used to update symlinks for commonly used executable names like ‘java’ on your Debian or Ubuntu install quickly.

codenomad@sparta:~/xruby$ export JAVA_HOME=/usr/lib/jvm/java-6-sun
codenomad@sparta:~/xruby$ chmod +x build.sh
codenomad@sparta:~/xruby$ ./build.sh

After this you should have an xruby-0.3.3.jar that will be used to compile Ruby code. Before I go any further, I’m going to move the xruby-0.3.3.jar to a more convenient location inside my ~/Code folder.

codenomad@sparta:~/xruby$ mv xruby-0.3.3.jar /home/codenomad/Code/
codenomad@sparta:~/xruby$ cd /home/codenomad/Code/

Now, let’s start writing some Ruby code using a simple “hello world” script. Create a file called hello.rb and add the following lines.

#!/usr/bin/ruby
puts "Hello World"

Lets make the Ruby script executable, and test it out:

codenomad@sparta:~/Code$ chmod +x hello.rb
codenomad@sparta:~/Code$ ./hello.rb
Hello World
codenomad@sparta:~/Code$

Cool, we have a working Ruby script. Now lets Java-fy it!

codenomad@sparta:~/Code$ java -jar xruby-0.3.3.jar -c hello.rb
Generated hello.jar
codenomad@sparta:~/Code$

It took me a little bit to figure out how to invoke my new found bytecode, but I’ve found that the easiest way is to put the xruby JAR and the hello.jar in the classpath and execute the main class stored inside the hello.jar. You can inspect the compiled JAR if you expand it, but I’ll save you the trouble and tell you that the main class is located at xruby.hello.main. So, let’s be sure our Ruby script works:

codenomad@sparta:~/Code$ java -cp xruby-0.3.3.jar:hello.jar xruby.hello.main
Hello World
codenomad@sparta:~/Code$

As you will see, it works as advertised but it really doesn’t show us a whole lot. Let’s try something that spins the CPU a bit more with a simple Fibonacci number calculator.

I included a timer in the code to keep track of any performance increase using XRuby. So, first create a file called fib.rb and add the following lines:

#!/usr/bin/ruby
require 'time'
puts "starting fibonacci"
def fib(num)
  if(num < 2)
    return 1
  else
    return fib(num-1) + fib(num-2)
  end
end

if ARGV[0] != nil
  if (ARGV[0].to_i >= 35)
    puts "This might take a bit...."
  end
  start = Time.now
  puts fib(ARGV[0].to_i)
  stop = Time.now - start
  puts "Finding the fib of #{ARGV[0]} took:"
  puts stop
  puts "seconds"
end

Let’s make the new file executable and run it just as a sanity check:

codenomad@sparta:~/Code$ chmod +x fib.rb
codenomad@sparta:~/Code$ ./fib.rb 20
starting fibonacci
10946
Finding the fib of 20 took:
0.135409
seconds
codenomad@sparta:~/Code$

Now let’s compile it to Java bytecode, and execute the script using XRuby.

codenomad@sparta:~/Code$ java -jar xruby-0.3.3.jar -c fib.rb
Generated fib.jar
codenomad@sparta:~/Code$ java -cp xruby-0.3.3.jar:fib.jar xruby.fib.main 20
starting fibonacci
10946
Finding the fib of 20 took:
0.083
seconds
codenomad@sparta:~/Code$

There is at least a noticeable speed up doing this. To really see a speed increase let’s try a bigger number like 35…

codenomad@sparta:~/Code$ ./fib.rb 35
starting fibonacci
This might take a bit....
14930352
Finding the fib of 35 took:
187.172469
seconds
codenomad@sparta:~/Code$

Wow, that’s a pretty long run for such a little number, let’s try the bytecode run:

codenomad@sparta:~/Code$ java -cp xruby-0.3.3.jar:fib.jar xruby.fib.main 35
starting fibonacci
This might take a bit....
14930352
Finding the fib of 35 took:
42.199
codenomad@sparta:~/Code$

I hope any questions about a performance increase were put to rest. The XRuby invocation of this simple Fibonacci script was 4.435 times faster than the native Ruby script! Granted you might not be able to convert every Ruby script that exists out in the wild, but if you write a script using the base libraries you can benefit quite a bit just by converting to Java bytecode.

Despite the lack of Rails support, the performance gain alone is enough to check this project out. If you do, let us know!

Share This on Your Favorite Social Network:
  • Facebook
  • MySpace
  • Twitter
  • Digg
  • StumbleUpon
  • LinkedIn
  • Reddit
  • FriendFeed
  • Tumblr
  • Suggest to Techmeme via Twitter
  • Technorati
  • Mixx
  • Propeller
  • Fark
  • Slashdot
  • del.icio.us
  • Google Bookmarks
  • Yahoo! Buzz
  • Print
, , , , ,

This post was written by:

Ray Gomez - who has written 46 posts on kallasoft.

Ray, a Linux and Unix nut, spends a majority of his daily ritual programming and testing for Big Blue. In his free time he manages to tweak the currently running thinkpad+KDE4 (WHOA) setup, read, and he occasionally gets out of the fluorescent lights to play roller hockey.

Contact the author

4 Responses to “Using XRuby to Speed up Ruby Script Performance”

  1. Wayne Bagguley Says:

    It’s still way slower than pure Java which does fib(35) in 0.187 seconds on my machine.

    Reply

    • Doug Hoover Says:

      Is your Java implementation recursive like the ruby being tested, or a loop? The recursive implementation is exponential time, the loop linear.

      Reply

  2. Mireille Cadlett Says:

    Twitter are a MUST for webmasters!

    Reply

Trackbacks/Pingbacks

  1. Ruby 1.9 Quick Speed Test | kallasoft - 04. Jan, 2009

    [...] but an 8x improvement on this simple recursive script? I was astonished! This is better than using XRuby to speedup Ruby performance! Share This on Your Favorite Social [...]

Leave a Reply