anchor.diff:        try Module:quit() catch _:undef -> ok end
     end.
   
  -%% @doc Compares the different runs of Module:Function to a given function.
  -%%      Returns the standard deviation of the distances between them (outliers excluded).
  -%%      The higher the value the more different functions are.
  --spec compare(atom(), atom(), atom() | fun((pos_integer()) -> number()), [option()]) -> float().
  -compare(Module, Function, MathFunction, Options) when is_atom(MathFunction) ->
  -  compare(Module, Function, fun(X) -> ?MODULE:MathFunction(X) end, Options);
  -compare(Module, Function, MathFunction, Options) ->
  -  RawResults = run(Module, Function, Options),
  -  Distances =
  -    [case {V, proplists:get_value(x, Options, 0) +
  -             (proplists:get_value(k, Options, 1) * MathFunction(K))} of
  -       {error, _} -> 0;
  -       {_, 0} -> 0;
  -       {V, M} -> M / V
  -     end || {K, V} <- RawResults],
  -  WithoutOutliers =
  -    lists:sublist(
  -      lists:sort(Distances), 1,
  -      proplists:get_value(rounds, Options, 250) - 2 * proplists:get_value(outliers, Options, 20)),
  -  Avg = lists:sum(WithoutOutliers) / length(WithoutOutliers),
  -  case proplists:get_bool(debug, Options) of
  -    true -> ?INFO("~p~n", [lists:sort(Distances)]);
  -    false -> ok
  -  end,
  -  do_graph(RawResults, MathFunction, Options),
  -  lists:sum([case Distance of
  -               Distance when Distance >= Avg -> Distance - Avg;
  -               _ -> Avg - Distance
  -             end || Distance <- Distances]) / length(Distances).
  -%% math:sqrt([(Distance - Avg) * (Distance - Avg) / Avg || Distance <- Distances])).
  -
  -%% @doc Compares the different runs of Module:Function/1 to a given function.
  -%% @equiv compare(Module, Function, [])
  --spec compare(atom(), atom(), atom() | fun((pos_integer()) -> number())) -> float().
  -compare(Module, Function, MathFunction) ->
  -  compare(Module, Function, MathFunction, []).
  -
  -%% @doc Graphs the results of running Module:Function/1 using ASCII Art
  -%% @equiv graph(Module, Function, [])
  --spec graph(atom(), atom()) -> ok.
  -graph(Module, Function) ->
  -  graph(Module, Function, []).
  -
  -%% @doc Graphs the results of running Module:Function using ASCII Art
  -%% @equiv graph(Module, Function, zero, Options)
  --spec graph(atom(), atom(), [option()]) -> ok.
  -graph(Module, Function, Options) ->
  -  graph(Module, Function, zero, Options).
  -
  -%% @doc Graphs the results of running Module:Function using ASCII Art
  --spec graph(atom(), atom(), atom() | fun((pos_integer()) -> number()), [option()]) -> ok.
  -graph(Module, Function, MathFunction, Options) when is_atom(MathFunction) ->
  -  graph(Module, Function, fun(X) -> ?MODULE:MathFunction(X) end, Options);
  -graph(Module, Function, MathFunction, Options) ->
  -  do_graph(run(Module, Function, Options), MathFunction, Options).
  -
  -%% ====================================================================
  -%% Math functions
  -%% ====================================================================
  -%% @doc O(1) comparer
  --spec zero(pos_integer()) -> pos_integer().
  -zero(_) -> 0.
  -
  -%% @doc O(1) comparer
  --spec constant(pos_integer()) -> pos_integer().
  -constant(_) -> 1.
  -
  -%% @doc O(n) comparer
  --spec linear(pos_integer()) -> pos_integer().
  -linear(N) -> N.
  -
  -%% @doc O(n^2) comparer
  --spec quadratic(pos_integer()) -> pos_integer().
  -quadratic(N) -> N * N.
  -
  -%% @doc O(log(n)) comparer
  --spec logarithmic(pos_integer()) -> float().
  -logarithmic(N) -> math:log(N) + 1.
  -
  -%% @doc O(n*log(n)) comparer
  --spec xlogarithmic(pos_integer()) -> float().
  -xlogarithmic(N) -> N * math:log(N) + 1.
  -
  -%% @doc O(e^n) comparer
  --spec exponential(pos_integer()) -> float().
  -exponential(N) -> math:pow(2.71828182845904523536028747135266249775724709369995, N).
  -
  -%% ====================================================================
  -%% Internal functions
  -%% ====================================================================
   do_run(Module, Function, Options) ->
     ok = try Module:init_per_testcase(Function) catch _:undef -> ok end,
     Start = proplists:get_value(start, Options, 1),
     try lists:map(fun(N) -> do_run(Module, Function, N, Options) end,
  -        lists:seq(
  -                  Start,
  -                  Start +proplists:get_value(rounds, Options, 250) *
  +        lists:seq(Start,
  +                  Start + proplists:get_value(rounds, Options, 250) *
                       proplists:get_value(step, Options, 1),
                     proplists:get_value(step, Options, 1)))
     after
  
positive.code:    {init, 0}, {init_per_testcase, 1}, {init_per_round, 2},
     {quit, 0}, {quit_per_testcase, 1}, {quit_per_round, 2}].
  
  %% @doc Runs all the benchmarking functions on Module.
  %%      The list is obtained calling Module:all().
  -spec run(atom()) -> [{atom(), [{pos_integer(), error | pos_integer()}]}].
  run(Module) ->
    ok = try Module:init() catch _:undef -> ok end,
    try
      lists:map(fun(Function) ->
                        {Function, do_run(Module, Function, [])}
                end, Module:all())
    after
        try Module:quit() catch _:undef -> ok end
    end.
  
  %% @doc Runs the benchmarking function Module:Function/1.
  %% @equiv run(Module, Function, [])
  -spec run(atom(), atom()) -> [{pos_integer(), error | pos_integer()}].
  run(Module, Function) ->
    run(Module, Function, []).
  
  %% @doc Runs the benchmarking function Module:Function using options.
  -spec run(atom(), atom(), [option()]) -> [{pos_integer(), error | pos_integer()}].
  run(Module, Function, Options) ->
  
negative.code: 
  -include("edis.hrl").
  
  -record(symbols, {up_up     = $" :: char(),
                    up_down   = $= :: char(),
                    up_none   = $^ :: char(),
                    none_up   = $ :: char(),
                    none_down = $_ :: char(),
                    none_none = $\s:: char(),
                    down_up   = $+ :: char(),
                    down_down = $. :: char(),
                    down_none = $, :: char()}).
  
  -type option() :: {start, pos_integer} | {step, pos_integer()} | {rounds, pos_integer()} |
          {extra_args, [term()]} | {outliers, pos_integer()} | {columns, pos_integer()} |
          {first_col, pos_integer()} | {rows, pos_integer()} | debug | {k, number()} | {x, number()}.
  -export_type([option/0]).
  
  -export([bench/4, bench/3, bench/2, behaviour_info/1]).
  
  -export([zero/1, constant/1, linear/1, quadratic/1, logarithmic/1, xlogarithmic/1, exponential/1]).
  
  