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.
Rob really nailed it with this blog entry. He's talking about how and why great developers get booted up into the management track and why that's a really dumb way to treat your tech talent, not to mention just plain bad business.
You can read about the same idea on Wikipedia under the Peter Principle article. It basically says that we are promoted to our level of incompetence, then we get trapped there. Very few people have the insight or courage to bail from the bad position and get back to what they love and do well.
When I give my talk on Software Development Techniques and in Shipper's Unite I talk about the role of a technical lead. I encourage people to try this role out once during their career. It gives you a different perspective on software. The danger is when you allow the words manager to creep into your title. At that point someone's going to look at your job and think it's full-time management. Working as a tech lead, you at least have a chance to write code as well as direct the project. It's what Rob refers to as running a small team. I call it being a tech lead, but the idea is the same.
Talk to the great technical talents you know. I'll bet that every one of them has worked in a management role at least once during their career... then run screaming into the night. :)
In fact, here's a measure of how great your company is. Does someone in management have to leave the company to get back into code or can they transfer "back down" into code?
So try it out once, but as a tech lead, not as a manager. Maybe even time box the experience. One quarter or one year? It's a great way to give developers a taste of management to cure them of silly aspirations... (some people are convinced they should be managers, but they have not idea what that means). This can also help you build your leadership from within your team. Some of you will love it... some will hate it, but we'll all be better developers with the extra experience under our belts.
Act fast and get your discount to see Andy Hunt and myself in the first Ship It! LIVE: DC Edition.
The early bird discount expires June 29th. Act now. Operators are standing by.
Ship It! LIVE: DC Edition
FYI, this is only scheduled Ship It! LIVE on the east coast.
I'm often asked what static code tools I like for Java. First, I've been nearly full-time in Ruby and Rails for a year now, so I may be out of date, but here's what I like.
Findbugs
Findbugs is the absolute best tool for static code analysis. But best is a nebulous and somewhat relative term. I prefer something with a very low noise to signal ratio, and Findbugs has that. Other tools (like PMD, see below) report a lot more information. So much in fact that real issues can get lost in the clutter.
Here's a quote for you... I've never run Findbugs on a production codebase and not found at least one legitimate bug. A real, not theoretical, issue.
Findbugs is free (open source even!) and the rule set can be edited with an XML file. They have an online (Java Web Start) version, Eclipse plugins, and more. It's an all around a great tool.
PMD
I don't like PMD as much because it has so much information in the reports. The good tends to lost in the false hits. However, after you've gotten your product in good enough shape that Findbugs runs cleanly, then PMD is your next step. You'll have to work a bit harder to find the good results, but it's worth the effort.
CPD
A real gem in the PMD toolbox is the invaluable Copy/Paste Detector (CPD). This tool will scan your entire codebase and point out every place where someone has lifted a bit of code.
The problem with the copied code is when you fix a bug in one spot, the fix is rarely copied around to all the pasted code. When you spot duplicate code with CPD, take a long hard look and see if you can't pull that code into a utility class. This won't catch everything that violates the DRY principal, but it's a good start.
UPDATE:
Tom Copeland sent me some extra CPD information. CPD also has a web-based launcher here so you can try out CPD without having to install the entire PMD suite. He also mentioned the PMD Applied book and said that chapter 5 goes into great detail on CPD.
Thanks Tom!
Code Coverage
You should be running a good code coverage tool to see what code your automated tests hit (or your manual tests for that matter). There are several great tools available, but I'm partial to Cobertura. It's a solid tool with great, easy to read reports. There are several other great tools available (Emma and Clover come to mind).
I'm not religious about my code coverage numbers... I don't think you need to set a code coverage number and make it a goal. I'm more concerned with using code coverage as a guide to direct my efforts.
Another tool inside Cobertura that you can use to direct those efforts is the Cyclomatic Complexity number. I've found it to have a direct correlation to code with bugs. The more complicated the code is, the more likely it is to have problems.
Continuous Integration
How often and from where should you be running these tools? Every time you touch the code of course. You don't want out of date reports do you? :)
Read Martin Fowler's classic article Continuous Integration, then go download the binary release of Cruise Control. The latest release has a nice Dashboard (see Jeffery Fredick's blog entry about the 2.7 release.)
I like to roll my static code tools into an Ant task and then run them from within Cruise Control. I publish the reports as part of the project's artifacts. This ensures things are always up to date, as well as providing a historical reference point I can revisit.
There are other popular CI tools available to you as well. These days Bamboo and Hudson are becoming more popular. This CI product matrix is a little out date, but a good starting point if you want the lay of the land.
Agitar
I've pointed you at a lot of open source tools... let me point you at one really big commercial offering. Agitar covers most of what I've listed above, and a lot more, including automated test generation. (Never let those automated tests replace a culture of great hand-crafted tests... use them to supplement, not replace.) Some companies just feel the need to have a commercial product in place. If you work there, check out the Agitar suite.
How Much?
If you put too many analysis tools and reports on a single page, developers tend to ignore them all. Pick one or two at first. This blog entry is a nice write up of one of my favorite strategies.
I hope this gives you a few options to check out. Just be sure not to overload the "customer" with too much information at one time. Start small and branch out.
Enjoy!
ps. Did I miss a tool or category? Drop me a line!