[erlang-questions] ring benchmark results: Is Erlang crazy fast?

David Cabana <>
Sat Jul 21 15:58:14 CEST 2007


Joe Armstrong proposed an exercise in Programming Erlang :
"Write a ring benchmark. Create N processes in a ring. Send a message  
round the ring M times. So that a total of N * M messages get sent.  
Time how long this takes for different values of N and M."

I did so, but I am having a hard time accepting the results. I am  
running latest the DarwinPorts build of Eralang on a G4 PowerBook.   
I'll post results, my reservations, and source code in that order.

%% --- results, pasted from console session
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0]  
[hipe] [kernel-poll:false]

Eshell V5.5.5  (abort with ^G)
1> c(ring).
{ok,ring}
2> ring:start(5000,10).
Total time=10 (32) milliseconds
ok
3> ring:start(5000,10000).
Total time=20 (26) milliseconds
ok
4> ring:start(5000,10000000).
Total time=10 (36) milliseconds

I find it hard to believe Erlang can send 50 billion messages in 36  
milliseconds on my hardware.  Can anyone give me a sanity check here?

Here's the code.  I left in some (commented out) diagnostic code;  
using it with small values of M and N leads me to think the program  
is doing what it is supposed to do. I am an Erlang newb; this is the  
longest and least trivial Erlang program I've written. Any  
observations on better style would be welcome.

-module(ring).
-export([start/2, foo/1, bar/0]).
%%
%% per Armstrong's "Programming Erlang"
%% Write a ring benchmark. Create N processes in a ring. Send a  
message round the ring M times.
%% So that a total of N * M messages get sent. Time how long this  
takes for different values of N and M.
%%

foo(Next) ->
     receive        %% foo does not care about the value of 2nd  
element in {x,y}, only bar does
	{0, Any} ->
	    % io:format("foo done ~n",[]),
	    Next ! {0, Any};	%% send the 0 along to tell everyone to shut down
	{N, Any} ->
	    % io:format("  foo ~p  ~n", [N]),
	    Next ! {N-1, Any},
	    foo(Next);	
	Other -> io:format("foo: huh? ~p ~n", [Other])
     end.

bar() ->
     receive
	{0, Next} ->
	    % io:format("bar done ~n",[]),
	    Next ! {0, Next};
	{N, Next} ->
	    % io:format("bar ~p  ~n", [N]),
	    Next ! {N-1, Next},
	    bar();
	Other -> io:format("bar: huh? ~p ~n", [Other])	
     end.

%% construct a chain of processes
%% process J-1 routes msgs to process J for all J < K
chain(0, Pid) -> Pid;
chain(K, Pid) -> chain(K-1, spawn(ring,foo,[Pid])).

%% N is the number of processes in the ring
%% M is the number of times msgs circle the ring
start(N, M) ->
     statistics(runtime),
     statistics(wall_clock),

     A= spawn(ring, bar, []),
     B= chain(N-1, A),
     A ! {N*M, B},

     {_, RT} = statistics(runtime),
     {_, WC} = statistics(wall_clock),
     io:format("Total time=~p (~p) milliseconds~n", [RT, WC]).





More information about the erlang-questions mailing list