The mind is like a parachute. If it doesn't open, you're meat.

Ruby Performance: What a difference the compiler makes

10 May 2011

For a long time Ruby performance was not an issue. That changed as soon as I moved from Windows to Mac and started supporting development teams on different systems.

Ruby performance under Windows was(is) an embarrassment (when it isn’t a reason to change development environment).

When writing software like build systems there is the factor of perceived performance which can be best defined as the amount of time between starting a program and the moment the first output is given to the user (the startup time) or the amount of time between screen outputs.

Providing clues to the user might actually slow down your scripts (all those stdout prints cost time) but it gives your user the sense that something (hopefully useful) is happening.

Then there is the real performance and lately I have reduced everything down to a single rule: minimize disk I/O.

For a build system that compiles stuff from source there is only so much you can do, but the rule holds.

When my team labeled our startup time the “Ruby Tribute Minute” I knew I couldn’t ignore the problem anymore. In order to keep up with a rapidly growing code base I had to improve performance: run fast in order to stay put.

The platform is Windows 7 32bit and to make matters worse I/O wise, it’s a virtual machine.

RubyInstaller 1.8.7p249 with DevKit 3.4.5 was the original installation. The update is RubyInstaller 1.8.7p334 with DevKit 4.5.1 and recompiled native gems.

Using the same codebase and running over the same amount of code the following graph shows the performance boost that Ruby gets from using a newer compiler on Windows.

That first bar is very important. It’s a rake -T, the closest thing to measuring the RTM. The p249 version needs 11 seconds while the p334 version under 5 (the same operation on my MacBook Pro needs 2 seconds but the comparison is useless since there are less cores and no VM)

The test is very realistic, in that it’s a sequence of rake calls from a living, growing build system: -T, clean, generate, build-1, build-1, build-2, build-2.

The last four measure time for a full rebuild and the minimum incremental build time for our two main targets. Where the compiler actually does the bulk of the job (bars 5 and 7) there is no gain but in every other aspect the new RubyInstaller version is faster and feels faster - it actually feels faster than it is, which goes a long way to placate my team members.

I’m actually quite interested to see what 1.9.2 performance looks like, but need to work out some incompatibilities first.

All I can do is send a great big thanks to Luis Lavena and the RubyInstaller team for doing such a great job and improving the Ruby experience on Windows immensely.

blog comments powered by Disqus