The amount of precision times have in databases is variable, so we need
tolerances when comparing in specs. It's better to have the tolerance defined
in one place than several.
This class method can be used in "describe" blocks to specify the
subject of a benchmark. This lets you write:
benchmark_subject { Foo }
instead of:
benchmark_subject { -> { Foo } }
This benchmark suite uses benchmark-ips
(https://github.com/evanphx/benchmark-ips) behind the scenes. Specs can
be turned into benchmark specs by setting "benchmark" to "true" in the
top-level describe block like so:
describe SomeClass, benchmark: true do
end
Writing benchmarks can be done using custom RSpec matchers, for example:
describe MaruTheCat, benchmark: true do
describe '#jump_in_box' do
it 'should run 1000 iterations per second' do
maru = described_class.new
expect { maru.jump_in_box }.to iterate_per_second(1000)
end
end
end
By default the "iterate_per_second" expectation requires a standard
deviation under 30% (this is just an arbitrary default for now). You can
change this by chaining "with_maximum_stddev" on the expectation:
expect { maru.jump_in_box }.to iterate_per_second(1000)
.with_maximum_stddev(10)
This will change the expectation to require a maximum deviation of 10%.
Alternatively you can use the it block style to write specs:
describe MaruTheCat, benchmark: true do
describe '#jump_in_box' do
subject { -> { described_class.new } }
it { is_expected.to iterate_per_second(1000) }
end
end
Because "iterate_per_second" operates on a block, opposed to a static
value, the "subject" method must return a Proc. This looks a bit goofy
but I have been unable to find a nice way around this.