Skip to content

Instantly share code, notes, and snippets.

@utgarda
Created December 8, 2010 16:51
Show Gist options
  • Save utgarda/733538 to your computer and use it in GitHub Desktop.
Save utgarda/733538 to your computer and use it in GitHub Desktop.
Tutorial problem from "Programming Erlang" by Joe Armstrong , 8.11 Write a ring benchmark. Create N processes in a ring. Send a msage round the ring M times so that a total of N * M messages sent. Time how long this takes for different values of N and M.
-module(ring_benchmark).
-export([new/2]).
new(N, M) ->
spawn(fun() -> spawn_ring(N, M) end).
spawn_ring(N, M) ->
io:format("First process: ~p~n", [self()]),
NextPid = spawn_rest(self(), N),
receive
ring_done -> io:format("Ring done.~n")
end,
_SentMessages = [NextPid ! {X, now()} || X <- lists:seq(0, M-1)],
%% io:format("Messages sent: ~p~n", [_SentMessages]),
collect_stats_loop(M, []).
spawn_rest(FirstPid, 0) ->
io:format("Last process: ~p , sending ring_done to ~p~n", [self(), FirstPid]),
FirstPid ! ring_done,
FirstPid;
spawn_rest(FirstPid, N) ->
%% io:format("More to spawn : ~p~n", [N]),
spawn_link(fun() ->
NextPid = spawn_rest(FirstPid, N-1),
resend_loop(NextPid)
end).
resend_loop(NextPid) ->
receive
Message -> NextPid ! Message
end,
resend_loop(NextPid).
collect_stats_loop(0, Acc) ->
ST = lists:foldl(fun({MsgNum, SendTime, ReceiveTime}, SummaryTime) ->
TravelTime = timer:now_diff(ReceiveTime, SendTime),
io:format("Message ~p travel time: ~p~n", [MsgNum, TravelTime]),
TravelTime + SummaryTime
end,
0,
Acc),
io:format("Summary message travel time : ~p~n", [ST]),
exit("Benchmarking done");
collect_stats_loop(M, Acc) ->
receive
{MsgNum, MsgSendTime} ->
collect_stats_loop(M-1, [{MsgNum, MsgSendTime, now()} | Acc])
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment