Skip to content

Instantly share code, notes, and snippets.

@kschlarman
Created September 11, 2012 02:11
Show Gist options
  • Save kschlarman/3695432 to your computer and use it in GitHub Desktop.
Save kschlarman/3695432 to your computer and use it in GitHub Desktop.
The Benchmark Module

##Benchmark The benchmark module provides an easy way to time how long your Ruby code takes to run. In this example, I will use the bm method to generate sequential reports with labels.

This bit of code compares two different ways to concatenate strings. It times how long it takes to concatenate a period at the end of a string of 10,000 a's, one million times in a row. The label for the each test is passed into the report method.

require 'benchmark'

Benchmark.bm do |x|
  # Test for concatenation with +=
  x.report("+= ") do
    1_000_000.times do 
      str = 'a'*10000
      str += "." 
    end
  end

  # Test for concatenation with <<
  x.report("<< ") do
    1_000_000.times do
      str = 'a'*10000
      str << "." 
    end
  end
end
       user     system      total        real
+=   7.230000   1.970000   9.200000 (  9.213903)
<<   5.890000   0.020000   5.910000 (  5.919318)

###Interpreting the results The results are reported in seconds and are divided into 4 columns. I usually just focus on the 'real' time column.

Our results show that, += takes 9.2 seconds while << only takes 5.9 seconds. Why is << so much faster? Well, it turns out that += will allocate an intermediate string, while << will append the second string directly to the end of the first with no extra allocation required.

###Consider bmbm for more accurate results If you run your test many times, you may notice variation in your results. These discrepancies can be caused by memory allocation and garbage collection. This is where the bmbm method has an advantage over the plain old bm. The bmbm method will run the test twice. The first execution is a “rehersal” to stabilize the environment. The second execution will theoretically give you more accurate results.

require 'benchmark'

Benchmark.bmbm do |x|
  x.report("+= ") do
    1_000_000.times do 
      str = 'a'*10000
      str += "." 
    end
  end

  x.report("<< ") do
    1_000_000.times do
      str = 'a'*10000
      str << "." 
    end
  end
end
Rehearsal ---------------------------------------
+=    6.800000   1.380000   8.180000 (  8.187169)
<<    5.550000   0.020000   5.570000 (  5.575393)
----------------------------- total: 13.750000sec

          user     system      total        real
+=    6.810000   1.580000   8.390000 (  8.387298)
<<    5.520000   0.010000   5.530000 (  5.541429)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment