Rails Template Optimizer Beta Test
Posted 15 Aug 2006
It's there. Finally. Get it while it's still hot. Be among the first to experience unprecedented rendering speed for Rails Erb templates ;-)
We all know and love the little helpers that Rails offers to speed up template coding. They're convenient and help us to keep the template code readable. But convenience almost always comes with a hidden performance cost. It's an unavoidable fact, at least in the IT business.
I started the Rails Template Optimizer project in order to reduce the hidden cost in using Rails helper methods. And I think the current version of this software shows that this is possible, to a great extent, although it is still in a beta state.
You can download the code from subversion. Since I'm pretty sure that there are still some bugs and problems with the code, I have set up a Trac installation. The start page contains information on how to obtain the template optimizer and links to additional information.
So, how does it work? And what kind of performance improvement can you expect?
Very early during my involvement in Rails performance improvement I observed that some of the Rails helpers would run rather slowly, most notably helpers that use route generation in some form. I worked around the problem by coding my own specialized methods (as decribed in my InfoQ article to avoid invoking the routing code at all. This was acceptable for my own purposes, but not really usable for larger applications, with complicated route setups. In addition, some of the helpers, especially those that create AJAX code, produce code so complicated that it would be insane to write it manually.
But after thinking about the problem for a while it dawned on me that a good part of the work the helpers were doing could be done once and for all at template compile time:
First, there are helper calls that have either no argument or all of their arguments specfied in the template code. These can safely evaluated when the template gets compiled. (Well, most of the time, the actual story is a bit more complicated than that. Use the source to find out more.)
Second, there are helper calls where the output produced depends to a large extent on the structure of the input data, and only slightly on the exact value of that data.
Consider the following link_to call:
link_to "Edit User",
{:controller => "user", :action => "edit", :id => @user},
{:class => "user_link"}
Assuming just the default routes, we know that this will always produce
<a href="/user/edit/#{@user.to_param}" class="user_link">Edit User</a>
And this is exactly the code that will be produced by the template optimizer at template compile time. It achieves this by performing a partial (symbolic) evaluation of the template code. (For details I'd like to refer you to the source code, for now.)
How much improvement will you get by using the optimizer? That's a tough question. It all depends on the actual source and may vary between no improvement at all and spectacular improvements.
As usual, I've benchmarked it. Here are two data sets. First, my own app with every link using link_to instead of my helpers.
page | c1 total | c2 total | c1 r/s | c2 r/s | c1 ms/r | c2 ms/r | c1/c2 |
---|---|---|---|---|---|---|---|
/rezept/show/413 | 8.15451 | 5.23208 | 122.6 | 191.1 | 8.15 | 5.23 | 1.56 |
/rezept/cat/Hauptspeise | 9.85367 | 4.68909 | 101.5 | 213.3 | 9.85 | 4.69 | 2.10 |
/rezept/cat/Hauptspeise?page=5 | 10.10721 | 4.84142 | 98.9 | 206.6 | 10.11 | 4.84 | 2.09 |
/rezept/letter/G | 9.86153 | 4.67950 | 101.4 | 213.7 | 9.86 | 4.68 | 2.11 |
Second, the admin interface of an older Typo version:
page | c1 total | c2 total | c1 r/s | c2 r/s | c1 ms/r | c2 ms/r | c1/c2 |
---|---|---|---|---|---|---|---|
/admin | 1.49967 | 0.85967 | 66.7 | 116.3 | 15.00 | 8.60 | 1.74 |
/admin/content | 7.01567 | 1.84333 | 14.3 | 54.2 | 70.16 | 18.43 | 3.81 |
/admin/pages | 2.99467 | 1.31767 | 33.4 | 75.9 | 29.95 | 13.18 | 2.27 |
/admin/categories | 4.51033 | 3.12500 | 22.2 | 32.0 | 45.10 | 31.25 | 1.44 |
/admin/sidebar | 4.88533 | 4.04133 | 20.5 | 24.7 | 48.85 | 40.41 | 1.21 |
/admin/themes | 3.58300 | 2.29667 | 27.9 | 43.5 | 35.83 | 22.97 | 1.56 |
/admin/users | 1.41167 | 0.77100 | 70.8 | 129.7 | 14.12 | 7.71 | 1.83 |
I would say these examples show some really nice improvement factors.
Enjoy.
Update:
You can svn co from http://railsexpress.de/svn/plugins/template_optimizer/trunk
And the template optimizer should now be compatible with rails 1.1.6