1%% @doc
2-module(meck_performance_test).
3
4%% Interface exports
5-export([run/0]).
6-export([run/1]).
7-export([run/2]).
8-export([new_unload/3]).
9
10%%=============================================================================
11%% Interface exports
12%%=============================================================================
13
14run() -> run(meck, 100).
15run(N) -> run(meck, N).
16run(Mod, N) ->
17    header(Mod),
18    run("new+unload", ?MODULE, new_unload, [Mod, test, [non_strict]], N),
19    Mod:new(test, [non_strict]),
20    run("expect/3", Mod, expect, [test, normal, fun() -> ok end], N),
21    run("expect/3+args", Mod, expect, [test, normal_args,
22      fun(_, _) -> ok end], N),
23    run("expect/4", Mod, expect, [test, shortcut, 0, ok], N),
24    run("expect/4+args", Mod, expect, [test, shortcut_args, 2, ok], N),
25
26    header("calls"),
27    Mod:expect(test, shortcut_opaque, 0, self()),
28    run("normal", test, normal, [], N),
29    run("normal_args", test, normal_args, [a, b], N),
30    run("shortcut", test, shortcut, [], N),
31    run("shortcut_args", test, shortcut_args, [a, b], N),
32    run("shortcut_opaque", test, shortcut_opaque, [], N),
33    Mod:unload(test),
34
35    header("history"),
36    Mod:new(test, [non_strict]),
37    Mod:expect(test, func, 1, ok),
38    [test:func(I) || I <- lists:seq(1, 100)],
39    run("called", Mod, called, [test, func, 50], N),
40    Mod:unload(test),
41    ok.
42
43new_unload(Mod, Mock, Opts) ->
44    Mod:new(Mock, Opts),
45    Mod:unload(Mock).
46
47%%=============================================================================
48%% Internal functions
49%%=============================================================================
50
51header(Name) ->
52    io:format("~n~s\t\tMin\tMax\tMed\tAvg~n", [Name]),
53    io:format("------------------------------------------------~n").
54
55run(Name, M, F, A, N) ->
56    io:fwrite("~-16s", [Name]),
57    io:format("~p\t~p\t~p\t~p~n", test_avg(M, F, A, N)).
58
59test_avg(M, F, A, N) when N > 0 ->
60    L = test_loop(M, F, A, N, []),
61    Length = length(L),
62    Min = lists:min(L),
63    Max = lists:max(L),
64    Med = lists:nth(round((Length / 2)), lists:sort(L)),
65    Avg = round(lists:foldl(fun(X, Sum) -> X + Sum end, 0, L) / Length),
66    [Min, Max, Med, Avg].
67
68test_loop(_M, _F, _A, 0, List) ->
69    List;
70test_loop(M, F, A, N, List) ->
71    {T, _Result} = timer:tc(M, F, A),
72    test_loop(M, F, A, N - 1, [T|List]).
73