Skip to content

Instantly share code, notes, and snippets.

Created January 21, 2009 22:10
Show Gist options
  • Save anonymous/50240 to your computer and use it in GitHub Desktop.
Save anonymous/50240 to your computer and use it in GitHub Desktop.
-module(bm).
-export([funs/4]).
-define(INDENT, 10).
funs(Module, Prefix, Args, N) when is_atom(Prefix) ->
Funs = [Fun || {Fun, Arity} <- Module:module_info(exports),
is_matched(Fun, Prefix),
Arity =:= length(Args)],
funs(Module, Funs, Args, N);
funs(Module, Funs, Args, N) when is_list(Funs) ->
Results = lists:foldl(fun(Fun, Results) ->
clear_line(),
io:format("~p...", [Fun]),
[{Fun, tc(Module, Fun, Args, N)} | Results]
end, [], Funs),
clear_line(),
print_results(lists:keysort(2, Results)).
is_matched(Fun, Prefix) ->
lists:prefix(atom_to_list(Prefix), atom_to_list(Fun)).
clear_line() ->
Columns = element(2, io:columns()) - 1,
io:format("\r~s\r", [lists:duplicate(Columns, $\s)]).
tc(Module, Fun, Args, N) ->
statistics(runtime),
statistics(wall_clock),
repeat(Module, Fun, Args, N),
{_, Runtime} = statistics(runtime),
{_, WallClock} = statistics(wall_clock),
{Runtime, WallClock}.
repeat(_, _, _, 0) ->
ok;
repeat(Module, Fun, Args, N) ->
apply(Module, Fun, Args),
repeat(Module, Fun, Args, N - 1).
print_results(Results) ->
FieldWidth = field_with(Results),
lists:foreach(fun({Fun, {Runtime, WallClock}}) ->
io:format("~*...w~p (~p) ms.~n", [-FieldWidth, Fun, Runtime, WallClock])
end, Results).
field_with(Results) ->
lists:foldl(fun({Fun, _}, MaxLen) ->
lists:max([MaxLen, length(atom_to_list(Fun))])
end, 0, Results) + ?INDENT.
-module(sample).
-compile(export_all).
bm() ->
bm:funs(?MODULE, decompress, [<<1,0,3,0,4,0,10,0,15,0,150>>], 500000).
bm2() ->
bm:funs(?MODULE, [decompress_1, decompress_2], [<<1,0,3,0,4,0,10,0,15,0,150>>], 500000).
decompress_1(Bin) when is_binary(Bin) ->
decompress_1(Bin, []).
decompress_1(<<0, Count, Tail/binary>>, Acc) ->
decompress_1(Tail, [<<0:(Count * 8)>> | Acc]);
decompress_1(<<Head, Tail/binary>>, Acc) ->
decompress_1(Tail, [Head | Acc]);
decompress_1(<<>>, Acc) ->
list_to_binary(lists:reverse(Acc)).
decompress_2(Bin) when is_binary(Bin) ->
decompress_2(Bin, <<>>).
decompress_2(<<0, Count, Tail/binary>>, Acc) ->
decompress_2(Tail, <<Acc/binary, 0:(Count * 8)>>);
decompress_2(<<Head, Tail/binary>>, Acc) ->
decompress_2(Tail, <<Acc/binary, Head>>);
decompress_2(<<>>, Acc) ->
Acc.
decompress_3(Bin) when is_binary(Bin) ->
decompress_3(Bin, []).
decompress_3(<<0, Count, Tail/binary>>, Acc) ->
decompress_3(Tail, [Acc, <<0:(Count * 8)>>]);
decompress_3(<<Head, Tail/binary>>, Acc) ->
decompress_3(Tail, [Acc, Head]);
decompress_3(<<>>, Acc) ->
list_to_binary(Acc).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment