Commits

Fred T-H committed f9dac7b

version 1 of benchmarking code added

  • Participants
  • Parent commits 349eebb

Comments (0)

Files changed (1)

File src/benchmark.erl

+-module(benchmark).
+-compile([export_all, debug_info]).
+
+%% The World
+world(Groups, ClientsPerGroup, Delay) ->
+    init_world(),
+    Pids = spawn_groups(Groups, ClientsPerGroup, []),
+    [receive {Pid, ready} -> ready end || Pid <- Pids],
+    io:format("All groups spawned. Ordering to message.~n"),
+    [Pid ! {self(),ok} || Pid <- Pids],
+    timer:sleep(Delay*1000),
+    io:format("Delay maxed. Compiling stats...~n"),
+    {Sent, Received} = compile_stats(Pids),
+    io:format("G:~p\tCPG:~p\tT:~p~n",[Groups,ClientsPerGroup,Delay]),
+    io:format("Sent: ~p~nReceived: ~p~n",[Sent,Received]),
+    io:format("Average sent per second: ~p~n", [Sent/Delay]),
+    io:format("Average received per second: ~p~n", [Received/Delay]),
+    io:format("Average sent per group: ~p~n", [Sent/Groups]),
+    io:format("Average received per group: ~p~n", [Received/Groups]),
+    io:format("Average sent per client: ~p~n", [Sent/(Groups*ClientsPerGroup)]),
+    io:format("Average received per client: ~p~n", [Received/(Groups*ClientsPerGroup)]),
+    io:format("Average sent per client per second: ~p~n", [Sent/(Groups*ClientsPerGroup)/Delay]),
+    io:format("Average received per client per second: ~p~n", [Received/(Groups*ClientsPerGroup)/Delay]),
+    ok.
+
+spawn_groups(0, _, Pids) -> Pids;
+spawn_groups(N, CPG, Pids) ->
+    S = self(),
+    Pid = proc_lib:spawn_link(fun() -> group(CPG,S) end),
+    spawn_groups(N-1, CPG, [Pid|Pids]).
+
+init_world() ->
+%    application:start(sasl),
+    application:start(chut).
+
+compile_stats(Pids) ->
+    [Pid ! {self(), stats} || Pid <- Pids],
+    lists:foldl(fun({X,Y},{XSum,YSum}) -> {X+XSum,Y+YSum} end,
+                {0,0},
+                [collect_stats() || _Pid <- Pids]).
+
+collect_stats() ->
+    receive
+        M={_,_} -> M
+    end.
+
+%% A group
+group(N, Parent) ->
+    Ids = [make_ref() || _ <- lists:seq(1,N)],
+    Pids = spawn_clients(Ids, [], []),
+    [receive {Pid,ready} -> ready end || Pid <- Pids],
+    Parent ! {self(), ready},
+    receive
+        {Parent,ok} -> ok
+    end,
+    [Pid ! {self(),ok} || Pid <- Pids],
+    receive
+        {From, stats} ->
+            Ratios = compile_stats(Pids),
+            From ! Ratios
+    end.
+
+spawn_clients([], _, Pids) -> Pids;
+spawn_clients([H|T], Done, Pids) ->
+    S = self(),
+    Pid = proc_lib:spawn_link(fun() -> client(H, T++Done, S) end),
+    spawn_clients(T, [H|Done], [Pid|Pids]).
+
+%% A client
+client(UserId, Peers, Parent) ->
+    chut_user:start(UserId, 60000, 10),
+    {ok, HandlerId} = chut_user:subscribe(UserId),
+    Parent ! {self(), ready},
+    receive
+        {Parent, ok} ->
+            client(UserId, HandlerId, 0, 0, Peers)
+    end.
+
+client(UserId, HandlerId, Sent, Received, Peers) ->
+    Dest = random(Peers),
+    chut_user:message(UserId, Dest, term_to_binary({<<"I've been mad for fucking years—absolutely years">>,os:timestamp()})),
+    {NewSent, NewReceived} = count_messages({UserId, HandlerId}),
+    receive
+        {From, stats} ->
+            From ! {Sent+NewSent, Received+NewReceived},
+%            chut_user:unsubscribe(UserId, HandlerId),
+            chut_user:terminate(UserId)
+    after 0 ->
+        client(UserId, HandlerId, Sent+NewSent, Received+NewReceived, Peers)
+    end.
+
+count_messages(Id) ->
+    lists:foldl(fun({Action,_,_}, {S,R}) ->
+                    if Action =:= received -> {S,R+1}
+                     ; Action =:= sent -> {S+1,R}
+                    end
+                end,
+                {0,0},
+                listen(Id)).
+
+listen(Id={_,Handler}) ->
+    receive
+        {Id, M = {_Action, _From, _Msg}} ->
+            [M | listen(Id)];
+        {gen_event_EXIT, Handler, normal} -> ok;
+        {gen_event_EXIT, Handler, Reason} -> exit({client,Reason})
+    after 0 -> []
+    end.
+
+random(L) when is_list(L) -> random(list_to_tuple(L));
+random(T) when is_tuple(T) ->
+    element(random:uniform(erlang:tuple_size(T)), T).