Benchmarking with Ruby 💎

A great technique to improve your code is using benchmarking – comparison between different solutions leads to faster and better code.

Ruby already has Benchmark module which can be used for measuring time of running of your code. For example lets compare string concatenation methods += and «:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'benchmark'

Benchmark.bm do |r|
  N = 100000

  r.report("+= ") do
    s = ""
    N.times { s += "1" }
  end

  r.report("<< ") do
    s = ""
    N.times { s << "1" }
  end
end

# =>         user           system        total         real
# => +=   1.060000   0.340000   1.400000 (  1.405588)
# => <<   0.030000   0.000000   0.030000 (  0.025614)

This case is great and you can see the huge difference between using += and « methods. But benchmark timing approach is not scientific – time depends on many params and the results will be different for each run. Good approach is to run your benchmark ‘experiment’ several times and than calculate average.

Take a look at #gem benchmark_suite, it is a great for benchmarking. Basically it provides extension for standart benchmark. So lets look at previous example implemented with benchmark_suite:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require 'benchmark'
require 'benchmark/ips'

Benchmark.ips do |r|
  N = 100000

  r.report("+= ") do
    s = ""
    N.times { s += "." }
  end

  r.report("<< ") do
    s = ""
    N.times { s << "." }
  end
end

# => Calculating -
# =>                 +=          1 i/100ms
# =>                 <<          3 i/100ms
# =>-
# =>                 +=         0.2 (±0.0%) i/s -          2 in   8.508143s
# =>                 <<        33.9 (±3.0%) i/s -        171 in   5.054061s

Also we can run benchmark without any N specified because report blocks will be executed multiple times:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'benchmark'
require 'benchmark/ips'

Benchmark.ips do |r|
  r.report("+ ") do
    42 + 42
  end

  r.report("* ") do
    42 * 42
  end
end

# =>Calculating -
# =>                  +      92249 i/100ms
# =>                  *      91950 i/100ms
# =>-
# =>                  +   6852082.4 (±6.8%) i/s -   34039881 in   4.998483s
# =>                  *   6280292.3 (±5.5%) i/s -   31263000 in   4.996057s

Obviously benchmark_suite takes longer time but the results are more precise. Use this technique to test your class methods, algorithms and for having fun!

Happy benchmarking!

P.S. First time I heard about benchmark_suite was at Toster conference in Moscow during the presentation by Jon Leighton, maintainer of ActiveRecord. Slides

“no fuss, just things you actually need”

Start learning with SQL Habit today

Master Data Analysis with SQL through the story of how a startup succeeded through data.
TRY 35 LESSONS FOR FREE

Explore other articles

2019

2018

2017

2014

2012