Benchmarking with benchmark-ips
Yesterday we looked at Ruby's built-in benchmark standard gem. It is a convenient and good choice to measure elapsed time for one block of code, or compare a few alternatives over a fixed number of iterations.
For microbenchmarks, though, choosing the number of iterations becomes challenging. Too few may give unreliable results. Too many means wasting time waiting for answers. The benchmark-ips gem solves this by measuring iterations per second, with warmup, repeated measurements and comparison output built in:
require "benchmark/ips"
path = "/users/123/profile"
prefix_regexp = /\A\/users\//
Benchmark.ips do |x|
# Warm up for 2 seconds, then measure for 5 seconds
x.config(warmup: 2, time: 5)
x.report("start_with?") do
path.start_with?("/users/")
end
x.report("regexp") do
path.match?(prefix_regexp)
end
x.compare!
end
# Output will vary by machine, but will look like:
#
# Warming up --------------------------------------
# start_with? 2.531M i/100ms
# regexp 1.865M i/100ms
# Calculating -------------------------------------
# start_with? 25.431M (± 1.9%) i/s (39.32 ns/i)
# regexp 18.702M (± 2.4%) i/s (53.47 ns/i)
#
# Comparison:
# start_with?: 25431240.7 i/s
# regexp: 18701920.3 i/s - 1.36x slower
What's also nice about the benchmark-ips output is that it includes standard deviation (± x.x%) and a comparison of the alternatives, so you can easily see how much faster one is than the other (1.36x slower).
For more options, including JSON output, independent runs with hold! and custom benchmark suites, refer to the benchmark-ips documentation.
History
benchmark-ips 1.0.0 was first released by Evan Phoenix on March 24, 2012.
Unlike benchmark, it is not bundled with Ruby, so you need to add it to your Gemfile or install it separately with gem install benchmark-ips.