OTP Performance

Matthew Sackman matthew@REDACTED
Sun Aug 20 13:10:55 CEST 2006


Hi,

Whilst I think I'm very familiar with the documentation or erlang.org,
this has probably been raised for, so feel free to point me in the
direction of the answers...

Exhibit 1:
-module(test).

-export([flood/1, flood/2, send/1, receiver/0]).

flood(Count) ->
    Target = spawn_link(test, receiver, []),
    Start = now(),
    flood(Count, Target),
    End = now(),
    io:format("~w~n", [timer:now_diff(End, Start)]),
    Target ! stop,
    ok.

flood(0, _Target) ->
    ok;

flood(N, Target) ->
    send(Target),
    flood(N-1, Target).

send(Target) ->
    Target ! ok.

receiver() ->
    receive
     stop ->
       exit(normal);
     _Else ->
       receiver()
    end.

and I get about 3.5 seconds for 10,000,000 messages.
Exhibit 2:
-module(test).

-behavior(gen_server).

-export([start_link/0, init/1, handle_cast/2, terminate/2]).
-export([flood/1, flood/2, send/1]).

flood(Count) ->
    {ok, Target} = start_link(),
    Start = now(),
    flood(Count, Target),
    End = now(),
    io:format("~w~n", [timer:now_diff(End, Start)]),
    gen_server:cast(Target, stop),
    ok.

flood(0, _Target) ->
    ok;

flood(N, Target) ->
    send(Target),
    flood(N-1, Target).

send(Target) ->
    gen_server:cast(Target, ok).

start_link() ->
    gen_server:start_link(test, {}, []).

init({}) ->
    {ok, {}}.

handle_cast(stop, State) ->
    {stop, normal, State};
handle_cast(_Any, State) ->
    {noreply, State}.

terminate(normal, _State) ->
    ok;
terminate(Code, State) ->
    io:format("Terminating ~w ~w~n", [Code, State]).

And it's now about 17 seconds for 10,000,000 messages. Now, I know that
gen_servers invokes functions via the Implicit Apply mechanism
(eg Mod:handle_cast), and that is expensive. So in many ways, these
results aren't surprising.

So my question is, what does this mean for applications that need to
achieve a very high throughput of messages a second?

1) Is there a body of applications where OTP has been avoided because it
hurts performance?

2) Are there other solutions that allow you to use OTP and maintain high
message throughput? For example, is it generally considered to have a
dozen or so processes that each do a little, and chain messages between
them, or have much fewer processes that each do a more sizeable chunk of
the work and thus reduce messaging costs?

3) Does Erlang implement copy on write for communication? If so, does
that mean that batching messages can be a win? E.g. rather than sending
the items of a list, send the list itself - does this actually reduce
the work done by Erlang (I realise this is a different matter from the
OTP-related questions)?

Many thanks,

Matthew
-- 
Matthew Sackman

BOFH excuse #135:
You put the disk in upside down.



More information about the erlang-questions mailing list