Skip to content

Instantly share code, notes, and snippets.

@pichi
Created October 29, 2017 15:59
Show Gist options
  • Save pichi/d09c8441e9c52a3181bcae7e3b0da30a to your computer and use it in GitHub Desktop.
Save pichi/d09c8441e9c52a3181bcae7e3b0da30a to your computer and use it in GitHub Desktop.
Tail vs Dirct recursion in Erlang
$ erl
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.1 (abort with ^G)
1> c(tail_vs_direct).
{ok,tail_vs_direct}
2> tail_vs_direct:compare().
[{5000,
{tail_c,{812,{total_heap_size,35462}}},
{direct,{519,{total_heap_size,28689}}}},
{10000,
{tail_c,{1332,{total_heap_size,92844}}},
{direct,{979,{total_heap_size,57380}}}},
{50000,
{tail_c,{7835,{total_heap_size,393300}}},
{direct,{2827,{total_heap_size,318186}}}},
{100000,
{tail_c,{8380,{total_heap_size,514838}}},
{direct,{7808,{total_heap_size,514838}}}},
{500000,
{tail_c,{69072,{total_heap_size,3800194}}},
{direct,{47487,{total_heap_size,2726992}}}},
{1000000,
{tail_c,{122515,{total_heap_size,5157867}}},
{direct,{95844,{total_heap_size,4560232}}}}]
3> tail_vs_direct:compare().
[{5000,
{tail_c,{695,{total_heap_size,35462}}},
{direct,{754,{total_heap_size,28689}}}},
{10000,
{tail_c,{1172,{total_heap_size,92844}}},
{direct,{872,{total_heap_size,57380}}}},
{50000,
{tail_c,{6486,{total_heap_size,393300}}},
{direct,{3112,{total_heap_size,318186}}}},
{100000,
{tail_c,{7300,{total_heap_size,514838}}},
{direct,{7363,{total_heap_size,514838}}}},
{500000,
{tail_c,{61023,{total_heap_size,3800194}}},
{direct,{39600,{total_heap_size,2726992}}}},
{1000000,
{tail_c,{116693,{total_heap_size,5157867}}},
{direct,{90386,{total_heap_size,4560232}}}}]
-module(tail_vs_direct).
-export([double_tail/1, double_direct/1, run/2, compare/0]).
double_tail(L) ->
double_tail(L, []).
double_tail([], Acc) -> lists:reverse(Acc);
double_tail([H|T], Acc) -> double_tail(T, [2*H|Acc]).
double_direct([]) -> [];
double_direct([H|T]) -> [2*H|double_direct(T)].
run(L, F) ->
Parent = self(),
G = fun() ->
{T, _} = timer:tc(fun() -> F(L) end),
Parent ! {self(), T, process_info(self(), total_heap_size)}
end,
Pid = spawn_link(G),
receive
{Pid, T, HS} -> {T, HS}
end.
compare() ->
[{N, {tail_c, run(L, fun double_tail/1)},
{direct, run(L, fun double_direct/1)}}
|| N <- [5000, 10000, 50000, 100000, 500000, 1000000],
L <- [lists:seq(1,N)]].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment