---
title: 'How-To: Quick Rails Benchmarking'
teaser:
tags: web,rails,performance
author: Harold Giménez
published_on: 2011-11-02
---

This February 6th we are launching a new workshop: [Advanced
Rails](http://workshops.thoughtbot.com/sections/29-advanced-rails). The workshop
draws content from the Scaling Rails and Rails Antipatterns workshops, replacing
them and creating best-of-breed content that will take your skill to the next
level in creating well-crafted Rails applications that scale.

One of the topics we touch on is profiling and benchmarking your app. There are
a number of tools available to achieve this, one of which is baked into Rails
itself. Although we do discuss all of the great ways you can perform caching in
a Rails app, experience has shown us that caching should be your last resource
in your scaling strategy. Remember the two hardest things in computer science:
Cache invalidation, naming things and off-by-one errors.

On to benchmarking, say you have identified an expensive method in one of your
models that needs to be tuned. One easy and straight-forward way to measure your
refactored process is to use the built in benchmarker to run quick tests. To get
set up, you need to add the `[ruby-prof](http://github.com/wycats/ruby-prof)`
gem to your Gemfile, and have a properly patched ruby interpreter. I'm using the
gcdata patch for <abbr title="Matz' Ruby Interpreter">MRI</abbr> 1.9.2:

    rvm install 1.9.2-p180 --patch gcdata --name gcdata

Now let's assume the following expensive method in the Account class:

    class Account
      def self.expensive_method
        sleep(1)
      end
    end

We can now run a quick benchmark on that method by running it [10
times](http://zedshaw.com/essays/programmer_stats.html) and taking some
benchmarking measurements:

    bundle exec rails benchmarker --runs 10 'Account.expensive_method'
    Loaded suite script/rails
    Started
    BenchmarkerTest#test_10 (0 ms warmup)
               wall_time: 0 ms
                  memory: 0 Bytes
                 objects: 0
                 gc_runs: 0
                 gc_time: 0 ms
    BenchmarkerTest#test_user_expensive_method (1.10 sec warmup)
               wall_time: 1.00 sec
                  memory: 0 Bytes
                 objects: 0
                 gc_runs: 0
                 gc_time: 0 ms

    Finished in 24.933979 seconds.

You can even run a profiler with `rails profiler 'Account.expensive_method' 10
flat` and get more information on what's being called and which components in
your system are taking longer.

With this quick benchmark, you can now create a second, hopefully optimized,
`Account.expensive_method_fast` and run them side-by-side, allowing you to
quickly measure two implementations of the same behavior, and allowing you to
quickly iterate to find the best solution.

This is just the tip of the iceberg. If you have some Rails experience and want
to take it to the next level to grow your app into a well-factored and scalable
system, check out our new [Advanced Rails
workshop](http://workshops.thoughtbot.com/sections/29-advanced-rails).
