Performance of send_message()

Pascal Brisset <>
Sat Aug 5 13:24:43 CEST 2000


 > Ah, this has almost reached the level of Frequently Asked Question :)

Indeed, I finally found plenty of information about the design
choices in an old thread about garbage collection
(http://www.erlang.org/ml-archive/erlang-questions/199908/msg00043.html).

But I'm still puzzled by the results of simple benchmarks
(definitely not representative of real applications):

- Why does is take O(N^2) time to queue N atoms, but O(N) to queue N
  lists ? (ok, forgetting to flush messages is bad programming).

- Why does process <0.25.0> need 8 times more collections (and time)
  than process <0.1.0> to do the same job ? According to
  process_info/1, they have the same priority, gc type, etc.

Pid <0.1.0>, 10000 'x': 0.05 s, {heap_size,2584}, GC {139,248554,0}
Pid <0.1.0>, 20000 'x': 0.16 s, {heap_size,2584}, GC {184,263973,0}
Pid <0.1.0>, 40000 'x': 0.66 s, {heap_size,2584}, GC {263,266034,0}
Pid <0.1.0>, 80000 'x': 2.98 s, {heap_size,2584}, GC {418,267637,0}
Pid <0.1.0>, 160000 'x': 13.11 s, {heap_size,2584}, GC {726,268279,0}
Pid <0.1.0>, 320000 'x': 56.39 s, {heap_size,2584}, GC {1343,270532,0}
Pid <0.1.0>, 640000 'x': 230.19 s, {heap_size,2584}, GC {2574,271433,0}

Pid <0.1.0>, 10000 '"x"': 0.03 s, {heap_size,75025}, GC {2587,273572,0}
Pid <0.1.0>, 20000 '"x"': 0.05 s, {heap_size,75025}, GC {2588,276331,0}
Pid <0.1.0>, 40000 '"x"': 0.15 s, {heap_size,317811}, GC {2593,316967,0}
Pid <0.1.0>, 80000 '"x"': 0.20 s, {heap_size,317811}, GC {2594,335806,0}
Pid <0.1.0>, 160000 '"x"': 0.71 s, {heap_size,1346269}, GC {2599,496442,0}
Pid <0.1.0>, 320000 '"x"': 0.93 s, {heap_size,1346269}, GC {2600,554721,0}
Pid <0.1.0>, 640000 '"x"': 2.68 s, {heap_size,2178309}, GC {2605,1510437,0}

Pid <0.25.0>, 10000 'x': 0.28 s, {heap_size,233}, GC {2776,2485639,0}
Pid <0.25.0>, 20000 'x': 1.18 s, {heap_size,233}, GC {3110,2486410,0}
Pid <0.25.0>, 40000 'x': 5.23 s, {heap_size,233}, GC {3779,2490093,0}
Pid <0.25.0>, 80000 'x': 24.58 s, {heap_size,233}, GC {5113,2490864,0}
Pid <0.25.0>, 160000 'x': 113.06 s, {heap_size,233}, GC {7781,2491635,0}
...

Running this with "erl -noshell -s msgsend run" on a AMD K6, 350MHz,
Linux RedHat 6.2. No swapping, no network activity, etc.

----------------------------------------------------------------------
-module(msgsend).
-export([run/0, scale/3]).

run() ->
    scale(x, 10000, 7),
    scale("x", 10000, 7),
    spawn(msgsend, scale, [x,10000,7]).

scale(Msg, N, 0) ->
    T0 = secs(), erlang:garbage_collect(), T1 = secs(),
    io:format("GC:~.2f s~n~p~n~n", [T1-T0, process_info(self())]);
scale(Msg, N, K) ->
    T0 = secs(), send(Msg, N), T1 = secs(),
    N = flush(),
    io:format("Pid ~p, ~p '~p': ~.2f s, ~p, GC ~p~n",
          [self(), N, Msg, T1-T0, process_info(self(), heap_size),
	         statistics(garbage_collection)]),
    scale(Msg, N*2, K-1).

send(Msg, 0) -> ok;
send(Msg, N) ->
    self()!Msg, self()!Msg, self()!Msg, self()!Msg, self()!Msg,
    self()!Msg, self()!Msg, self()!Msg, self()!Msg, self()!Msg,
    self()!Msg, self()!Msg, self()!Msg, self()!Msg, self()!Msg,
    self()!Msg, self()!Msg, self()!Msg, self()!Msg, self()!Msg,
    send(Msg, N-20).

flush() -> flush(0).
flush(N) -> receive _ -> flush(N+1) after 0 -> N end.

secs() -> {A,B,C} = now(), A*1.0e6 + B + C*1.0e-6.
----------------------------------------------------------------------

- Pascal Brisset <> +33 2 96051928 -
- France Telecom R&D DTL/MSV | 2, av Pierre Marzin | F-22307 Lannion -



More information about the erlang-questions mailing list