Benchee Build Status

Library for easy and nice (micro) benchmarking. It allows you to easily compare the performance of different pieces of code/functions. Benchee is also versatile and extensible.

Somewhat inspired by benchmark-ips from the ruby world, but of course it is a more functional spin.

Provides you with:

Benchee does not:

Installation

When available in Hex, the package can be installed as:

Add benchee to your list of dependencies in mix.exs:

def deps do
[{:benchee, "~> 0.1.0", only: :dev}]
end

Install via mix deps.get and then happy benchmarking as described in Usage :)

Usage

After installing just write a little benchmarking script:

list = Enum.to_list(1..10_000)
map_fun = fn(i) -> [i, i * i] end
Benchee.run(%{time: 3},
[{"flat_map", fn -> Enum.flat_map(list, map_fun) end},
{"map.flatten",
fn -> list |> Enum.map(map_fun) |> List.flatten end}])

First configuration options are passed, the only option available so far is time which is the time in seconds for how long each individual benchmark should run.

Running this scripts produces an output like:

tobi@happy ~/github/benchee $ mix run samples/run.exs
Benchmarking flat_map...
Benchmarking map.flatten...
Name ips average deviation median
map.flatten 1311.84 762.29μs (±13.77%) 747.0μs
flat_map 896.17 1115.86μs (±9.54%) 1136.0μs
Comparison:
map.flatten 1311.84
flat_map 896.17 - 1.46x slower

See the general description for the meaning of the different statistics.

It is important to note that the way shown here is just the convenience interface. The same benchmark in its more verbose form looks like this:

list = Enum.to_list(1..10_000)
map_fun = fn(i) -> [i, i * i] end
Benchee.init(%{time: 3})
|> Benchee.benchmark("flat_map", fn -> Enum.flat_map(list, map_fun) end)
|> Benchee.benchmark("map.flatten",
fn -> list |> Enum.map(map_fun) |> List.flatten end)
|> Benchee.statistics
|> Benchee.Formatters.Console.format
|> IO.puts

This is how the "functional transformation" works here:

  1. Configure general parameters
  2. run n benchmarks with the given parameters gathering raw run times per function
  3. Generate statistics based on the raw run times
  4. Format the statistics in a suitable way
  5. Output the formatted statistics

This is also part of the official API and allows a more fine grained control. Do you just want to have all the raw run times? Grab them before Benchee.statistics! Just want to have the calculated statistics and use your own formatting? Grab the result of Benchee.statistics! Or, maybe you want to write to a file or send an HTTP post to some online service? Just replace the IO.puts.

This way Benchee should be flexible enough to suit your needs and be extended at will.

Development

Happy to review and accept pull requests or issues :)