Benchmarking Portions of Your Application Code

Problem

When trying to isolate performance problems, it's not always obvious where the bottleneck in your code is. You want a way to benchmark portions of your application code, whether in a model, view, or controller.

Solution

You can use the benchmark class method of your model inside a controller to benchmark a block of code. For example:

app/controllers/reports_controller.rb:

class ReportsController < ApplicationController
 def show
 Report.benchmark "Code Benchmark (in controller)" do
 # potentially expensive controller code
 end 
 end 
end

Each call to benchmark takes a required title parameter you use to identify and distinguish it from other benchmarks when viewing the results in your logs.

Your models can use the same method:

app/models/report.rb:

class Report < ActiveRecord::Base
 def generate
 Report.benchmark("Code Benchmark (in model)") do
 # potentially expensive model code
 end 
 end 
end

In your views, you have the benchmark view helper, which you can use to wrap code in your views, such as rendered partials. For example:

app/views/reports/show.rhtml:

<h1>Show Reports</h1>
<% benchmark "Code Benchmark (in view)" do -%>
 <%= render :partial => "expensive_partial" %>
<% end -%>

Discussion

As the solution demonstrates, benchmark takes an identifying title parameter as well as two other optional parameters; the log level at which the benchmarks should run, and whether normal logging of the code being benchmarked should be silenced or not. The method signature looks like:

benchmark(title, log_level = Logger::DEBUG, use_silence = true) {|| ...} 

The log level defaults to DEBUG, which keeps the benchmarking from happening in production mode, by default and use_silence defaults to TRue. The output from all three calls in the solution show up in your logs as follows:

Processing ReportsController#show (for 127.0.0.1 at 2006-09-05 08:24:08) 
 [GET]
 Session ID: b16b2b7987619da67dde11f5d9105981
 Parameters: {"action"=>"show", "controller"=>"reports"}
Code Benchmark (in controller) (4.20695)
Rendering reports/show
Code Benchmark (in model) (1.00295)
Code Benchmark (in view) (1.00482)
Completed in 5.23700 (0 reqs/sec) | Rendering: 1.02216 (19%) | 
 DB: 0.00000 (0%) | 200 OK [http://localhost/reports/show]

See Also