I'm giving a talk at OSCON on extending your Rails application with C and I thought I'd blog on a few gotchas as I work on the demo application and publish my preliminary "benchmark". (Don't get upset... it's not really a benchmark.)
I'm going to use two technologies for my C integration. RubyInline is used for dropping C in line to your Ruby code, hence the clever name. It's really easy to use and has very good docs.
The other technology is the plain old Ruby C Extensions. This is also very easy to use.
RubyInline compiles the C code on your first pass and then reuses the compiled code. Putting that file in a controller that you reload with every client visit really messes it up. This reload is done in development mode, not production mode.
So you have two options, the first is to run your Rails app server in production mode. For Mongrel, try "mongrel_rails start -d -e production"
The other option is to put your Ruby class containing your C code in a location that isn't reloaded every time. I used the lib folder. On the other hand, this really slows down your Rails debugging. You have to restart your Rails app server between edits to the C code. It's almost like having to compile everything! ;) It'll drive you nuts.
Thanks to this Ruby mailing list thread for the answer to that problem.
Another issue to be aware of is that RubyInline seems to want your C code inside of double quotes. That's not a problem until you want to have a double quote in your C code. A printf perhaps? Just use the
%Q{ Put your string in here}
notation. That will quote anything within the brackets. Put all your C code within the brackets and you'll be fine.
Finally, when you do something like a factorial example, don't let the results get too big. Your C code will silently overflow and return a zero to you, making you think you've got a simple error in your C code. :) Just keep the results reasonable and you'll be fine. For the record, factorial of 500 isn't reasonable.
While RubyInline is easier to get started with, I think regular C extensions are easier to use. But something to remember... if you've been coding and developing with C extensions in a shell, you may have just been doing "make", and that works fine for that directory. But not for Rails. Don't forget that the rest of the system can't see your code until you do a "make install".
For my demo, I'm just using a boring, non-realistic factorial example. And I'm having to run it 50,000 times in a row to slow it down enough to have meaningful differences in the times. And that's on a laptop.
Raw ruby calculates factorial twelve 50,000 times in 0.53336 seconds, or just under 2 reqs/sec. That's within a Rails controller.
Using RubyInline, it takes 0.04724 seconds or 21 reqs/sec. Ten times faster.
C Extensions runs the same code in 0.02681 seconds or (37 reqs/sec). Almost twenty times faster.
I did notice that for larger factorial values, the time difference between RubyInline and C Extensions seemed to shrink significantly, so there must be some startup time involved... But the message is clear.
Write your application with all the speed of development that Rails can give you. Get it running, then bench it. If you need more speed than the runtime can provide, you can always drop back to doing the processor intensive work in C, giving you the best of both worlds.
Should you plan on using C in your next Rails application? No way. I'd bet that more than 99% of applications don't need that much performance. But if you do, it's nice to know it's available.