Subscribe to the iTunes Rails Screencast Feed Now!

How to Benchmark Your Code using benchmark-ips Gem

In this article, you will see how easy it is to start benchmarking your code. The Ruby version used is 2.3.0. First, install the benchmark-ips gem.

gem install benchmark-ips

The advantage of using this gem is that you don't need to guess the iteration number to benchmark your code. The gem automatically figures out the iteration number to use.

Dynamically Sending a Message to an Object

Let's compare sending message to an object using send vs using implicit send to execute code.

require 'benchmark/ips'

Benchmark.ips do |x|
  x.report('addition') { 1 + 2 }
  x.report('addition with send') { 1.send(:+, 2) }
  x.compare!
end

Run the benchmark.

$ ruby add.rb

Here is the performance results.

Warming up --------------------------------------
            addition   171.062k i/100ms
  addition with send   159.831k i/100ms
Calculating -------------------------------------
            addition     12.818M (± 2.5%) i/s -     64.148M
  addition with send      8.173M (± 2.1%) i/s -     40.917M

Comparison:
            addition: 12817978.9 i/s
  addition with send:  8173109.1 i/s - 1.57x slower

You can see using send is 1.57 times slower.

String Concatenation

Let's compare concatenating string using +=, << and concat.

require 'benchmark/ips'

Benchmark.ips do |x|
  x.report('concat with +=') do
    s = 'bat'
    s += 'mat'
  end
  x.report('concat with <<') do
    s = 'bat'
    s << 'mat'
  end
  x.report('concat with concat') do
    s = 'bat'
    s.concat('mat')
  end

  x.compare!
end

Run the benchmark.

ruby concat.rb

Here is the performance results.

ruby concat.rb
Warming up --------------------------------------
      concat with +=   143.335k i/100ms
      concat with <<   147.118k i/100ms
  concat with concat   142.974k i/100ms
Calculating -------------------------------------
      concat with +=      5.502M (± 1.6%) i/s -     27.520M
      concat with <<      5.678M (± 1.1%) i/s -     28.394M
  concat with concat      5.283M (± 2.8%) i/s -     26.450M

Comparison:
      concat with <<:  5678462.1 i/s
      concat with +=:  5502116.5 i/s - 1.03x slower
  concat with concat:  5283407.1 i/s - 1.07x slower

You can see << has the best performance. The += is 1.03 times slower than <<. The concat method is 1.07x times slower than <<. So we should prefer << over += or concat. Remember that anything that creates lot of objects will be slower. In this case, += creates new object everytime it concatenates a string to an existing object.

Parallel Assignment

Let's now compare parallel assignment with sequential assignment.

require 'benchmark/ips'

Benchmark.ips do |x|
  x.report('parallel') do
    a, b = 10, 20
  end

  x.report('sequential') do
    a = 10
    b = 20
  end

  x.compare!
end

Run the benchmark.

$ ruby assignment.rb 

Here is the performance results.

Warming up --------------------------------------
            parallel   163.915k i/100ms
          sequential   172.552k i/100ms
Calculating -------------------------------------
            parallel      9.089M (± 3.5%) i/s -     45.404M
          sequential     12.342M (± 3.4%) i/s -     61.774M

Comparison:
          sequential: 12341542.5 i/s
            parallel:  9088599.9 i/s - 1.36x slower

The parallel assignment is 1.36 times slower.

Summary

In this article, you learned how to use benchmark-ips gem to benchmark your code. It is a lot easier to interpret the results when you use benchmark-ips gem.

Reference

benchmark-ips

Sharing is Caring