Erlang ring benchmark

Posted by enrico
Thu, 22 May 2008 17:30:00 GMT

Trying to be a cool kid, I’ve recently spent some time playing with Erlang. So I’ve found in Joe Armstrong’s Programming Erlang the following exercise:

”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.

Write a similar program in some other programming language you are familiar with. Compare the results. Write a blog, and publish the results on the Internet! ”

(Already a classic now …).

I dutifully complied: here’s my solution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-module(ringu).
-export([start/2]).

% ----------------------------------------------------------------------

start(N, M) -> 
    Pid_0 = self(),
    statistics(runtime),
    statistics(wall_clock),
    Pid = spawn(fun() -> ringu(N, M, self(), Pid_0) end),
    Pid ! x,
    receive 
        _ -> true
    end,
    {_, TCPU} = statistics(runtime),
    {_, Time} = statistics(wall_clock),
    io:format("~nElapsed time: ~w ms~nCPU time:     ~w ms ~n" ,
          [Time, TCPU]).

% ----------------------------------------------------------------------

ringu(1, M, Pid_1, Pid_0) -> ringu_loop(M, Pid_1), Pid_0 ! itsover;
ringu(N, M, Pid_1, Pid_0) -> 
    ringu_loop(M, spawn(fun() -> ringu(N-1, M, Pid_1, Pid_0) end)).

ringu_loop(1, Pid) -> ringu_fwd_msg(Pid);   
ringu_loop(M, Pid) -> ringu_fwd_msg(Pid), ringu_loop(M-1, Pid).

ringu_fwd_msg(Pid) ->    
    receive 
        X -> Pid ! X %, io:format(".", [])
    end.

Benchmark results, and an (uneven :) ) comparison with an equivalent script in Ruby here.