This site is dedicated to further knowledge about creating Ruby on Rails applications professionaly. We discuss Ruby on Rails features from a performance angle, discuss Ruby on Rails performance analysis methods, provide information on Ruby on Rails scaling and benchmark Ruby on Rails performance for each release. We discuss best practices for selecting Ruby on Rails session containers, fragment and page caching and optimizing database queries.

SqlSessionStore now available as a plugin

Posted 15 Sep 2006

Rails core team member Rick Olson, the author of many rails plugins, mephisto and techno-weenie, has turned SQLSessionStore into a plugin and sent his code for me to publish. Thanks a lot Rick!

I incorporated the latest changes from my sql session store implementation, most notably postgresql support, and added sql_session_store to my trac installation.

Using sql_session_store is now easier than ever before. Check it out into your vendor/plugins directory:

svn co http://railsexpress.de/svn/plugins/sql_session_store/trunk  \
 sql_session_store

and follow the instructions in the README file.

If you find any problems with the plugin, which would be entirely my own fault, not Rick’s, please use Trac to report them.

BTW, I’d love to get support in for additional database adapters, especially Oracle. I you find the time to write an adapter, please submit the code using Trac, or email me.

View Comments

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 totalc2 total c1 r/sc2 r/s c1 ms/rc2 ms/r c1/c2
/rezept/show/413 8.154515.23208 122.6191.1 8.155.23 1.56
/rezept/cat/Hauptspeise 9.853674.68909 101.5213.3 9.854.69 2.10
/rezept/cat/Hauptspeise?page=5 10.107214.84142 98.9206.6 10.114.84 2.09
/rezept/letter/G 9.861534.67950 101.4213.7 9.864.68 2.11

Second, the admin interface of an older Typo version:

page c1 totalc2 total c1 r/sc2 r/s c1 ms/rc2 ms/r c1/c2
/admin 1.499670.85967 66.7116.3 15.008.60 1.74
/admin/content 7.015671.84333 14.354.2 70.1618.43 3.81
/admin/pages 2.994671.31767 33.475.9 29.9513.18 2.27
/admin/categories 4.510333.12500 22.232.0 45.1031.25 1.44
/admin/sidebar 4.885334.04133 20.524.7 48.8540.41 1.21
/admin/themes 3.583002.29667 27.943.5 35.8322.97 1.56
/admin/users 1.411670.77100 70.8129.7 14.127.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

View Comments

RailsConf2006 Aftermath

Posted 28 Jun 2006

As promised during my talk at RailsConf, I have uploaded a new version of my railsbench package to rubyforge. You can either download the tar ball or get the new version using svn. Apologies to all users which have a checked out and modified version of the old CVS archive. I decided to convert from CVS to subversion since I kept typing svn commands at my CVS archive, so it had to go.

The svn url for railsbench is svn://rubyforge.org//var/svn/railsbench/trunk/railsbench

The new version now supports running ruby-prof as an alternative to SVL's Ruby Performance Validator. This should make some Mac and Linux users happy. However, ruby-prof is only a weak substitute for a good profiler.

Profiling with ruby-prof requires ruby 1.8.4 and works like this:

perf_prof n "-bm=benchmark_name other_options" config_name

This will run the named benchmark n times using ruby-prof and store the resulting HTML formatted profiler graph into $RAILS_PERF_DATA

Happy profiling!

PS: My presentation given at RailsConf2006 is available for download.

View Comments

Common Rails Performance Problems

Posted 13 Jun 2006

InfoQ has published an article on common Rails performance problems (written by me). You can head over to read all about it.

View Comments

Simpler Piggy Backing

Posted 29 May 2006

A while ago I posted an article about the performance improvements obtainable by piggy backing. Although the speedups where substantial, I received some negative comments about exposing too much SQL to the programmer.

Exposure to the underlying SQL is not such a big problem for me, that it would deter me from applying the technique. But I found that I had a lot of repetition in my code, which I didn't like.

After ignoring the problem for a while, I decided it was about time to deliver a better solution than manually coding selects and joins.

I wrote a small extension to ActiveRecord, which makes piggy backing extremely simple.

Instead of coding joins and selects manually, you can now declare the piggy backed attributes from a has_one or belongs_to association in your model classes like so:

class Article
  belongs_to :user
  piggy_back :user_name_and_birthday, :user, :name, :birthday
end

This will generate all necessary select and join statements, which can then be added to a query rather elegantly:

article = Article.find :first,
            :piggy => :user_name_and_birthday,
            :conditions => "articles.title LIKE '%piggy%'"

would retrieve the first article which contains 'piggy' in its title attribute, along with the birthday and name attributes of the corresponding User object, storing them in the attributes hash of the AR instance.

But this is not all! After declaring the piggy backed attributes, you will also get reader methods which retrieve the attribute for you from the AR instance, and, should a type cast be required, convert the value to the correct type.

The piggy backed attributes are accessed like this:

article.user_name        ==> a string
article.user_birthday    ==> a date

Additionally, should you forget to piggy back a query,

article = Article.find :first,
            :conditions => "articles.title LIKE '%piggy%'"

methods user_name and birthday will silently use the user association to retrieve the values for you. This make is possible to use user_name and user_birthday regardless of whether your original query was piggy backed or not.

I've ensured that all of this works with pagination. In fact, using the extension is slightly faster than coding the select and joins manually (1%-3%).

You can download the code here. I haven't turned it into a plugin yet, so you need to add a require 'piggy_back' to your environment.rb.

Enjoy!

Update:

  • I failed to mention that piggy backing also works with finds on associations, so
article.comments.find(:all, :piggy => :user_name)

works as expected.

  • Upon popular demand it's now possible to use a more verbose syntax. You can write
class Article
  belongs_to :user
  piggy_back :user_name_and_birthday,
      :from => :user, :attributes => [:name, :birthday]
end

for the example above.

  • Piggy backing is now available as a plugin using the URL svn://railsexpress.de/plugins/piggy_back/trunk

View Comments

Older posts: 1 2 3 4 5 6 7 8 9