How Rails' Benchmarks Lie

Posted by Lance Ivy Wed, 28 Nov 2007 00:42:00 GMT

I’ve been on a benchmarking blogging spree lately. Creating BenchmarkForRails (B4R) with its non-invasive benchmarking technique has made it very easy to play around with timing of key Rails methods and develop a better picture of the true costs. The results have been amazing.

First of all, apologies to those of you still running Rails 1.2.x. B4R’s non-invasive technique only works well in Rails 2.0 due to some very nice refactoring, especially in Dispatcher and ActionController::Filters.

Blind Spots

Take a look at these benchmarks for the exact same request, as seen by Rails and B4R. This was done in development mode on an unoptimized page, so don’t worry too much about the times, ok? It’s the differences that are important.

Rails
Completed in 0.85246 (1 reqs/sec)
Rendering: 0.48872 (57%)
DB: 0.02561 (3%)
BenchmarkForRails
- [0.9532] GET /plans ----------------------------
   0.8528 processing action
   0.5015 rendering
   0.2533 activerecord find
   0.0461 development mode
   0.0073 before filters
   0.0046 session management
   0.0000 after filters
------------------------------ BenchmarkForRails -

The first line is from Rails’ built-in benchmarks. The following lines are from B4R. Please note that the benchmarks in B4R are not meant to add up, which is no different than Rails’ benchmarks.

Completion Time

Rails claims that the completion time was 0.85 seconds, and B4R claims that the completion time was 0.95. That’s a difference of 0.1 seconds. Big deal? It can be! But where’s the extra time coming from? Well, notice that B4R has an entry for “processing action”, and notice that this time (0.85) matches Rails’ declared completion time.

The problem is that there’s more machinery involved in handling a request then just processing the controller action. Here’s a quick list of some potentially significant things Rails is missing in its reported completion time:

  • routing recognition
  • before filters
  • after filters
  • session management

But these are all very real costs that you can (and should) strive to optimize. They’re costs you should know about. And they’re costs that definitely affect your requests-per-second.

DB Access

Rails’ idea of query costs is how much time was spent waiting for your database to answer, and so it comes back with an incredibly low 0.025 seconds. With numbers like that, why would anyone optimize queries! Why would anyone bother with eager-loading?

Pure database access time only matters for big queries. But if you make just ten small queries, the true costs are somewhere else: ActiveRecord’s query construction.

Now go back to the sample benchmarks above. Notice the “activerecord find” entry? That’s 0.25 seconds. No, it didn’t misplace the decimal – the real cost of executing queries on the page was 10x what Rails reported. Why? Because the database is faster than ActiveRecord, obviously.

So yeah, there’s some real motivation for eager loading, yeah?

Tags ,  | 5 comments

Comments

  1. pascal said 14 days later:

    awesome! this allowed me to discover a mysterious time leak in the session management and to get rid of requests taking over two seconds..

    we learned: - don’t put objects in your session, especially active records with associations - use memcached as session store (duh)

  2. Frederico Araujo said 23 days later:

    not to mention that if are on rails2 and using the default cookie store, your session will be limited to 4K.

  3. Frederico Araujo said 23 days later:

    I forgot to say:

    Thanks for the Plugin, it AWESOME!

  4. Eduardo Yáñez Parareda said 3 months later:

    Hello, how could I interpret this result: - [0.7180] POST /formation/change_player - 0.2810 action 0.1720 development mode 0.0940 rendering 0.0630 finders 0.0150 session 0.0000 filters ------ BenchmarkForRails -

    What means 0.718? And 0.281 action?

  5. Maxime Guilbot said 5 months later:

    thanks for the plugin, it’s really useful. Maybe should just be included in rails.

(leave url/email »)

   Comment Markup Help Preview comment