[erlang-questions] On selective receive (Re: eep: multiple patterns)

Ulf Wiger <>
Sat May 31 07:44:15 CEST 2008


I would really like to discourage people from avoiding
selective receive because it's "expensive". It can be
expensive on very large message queues, but this is
a pretty rare error condition, and fairly easily observable.

(I know of projects that have banned use of selective
receive for this reason, but without having thought much
about what to use instead, and when.)

You can use erlang:system_monitor/2 to quickly detect
if a process is growing memory in a strange way.

An old legacy Ericsson system implemented selective receive
in a way that the message queue could hold at most 6 messages.
Any more than that was obviously an error.

I think it might be useful to be able to specify such a limit as
a spawn option, perhaps together with maximum heap size.
Exceeding the limit could perhaps lead to the process being
killed (which might seem backwards in the case of the message
queue, but at least gives a visible indication), or that the sender
process would be suspended (which could potentially lead to the
whole system stopping.)

BR,
Ulf W

2008/5/31 Christopher Atkins <>:
> Hello, I tried (poorly--I'm a complete novice) to implement a benchmark from
> your earlier statement.  I didn't do the same thing (load up the message
> mailbox before consuming them), but what I did write led to a perplexing (to
> me) discovery.  If I uncomment the line in [loop1/0] below, performance for
> that loop degrades by an order of magnitude.  Why is that?
>
> -module(test_receive).
> -compile(export_all).
>
> start() ->
>         statistics(runtime),
>         statistics(wall_clock),
>         PidLoop1 = spawn(?MODULE, loop1,[]),
>         sender(PidLoop1, 10000000),
>         {_, Loop1Time1} = statistics(runtime),
>         {_, Loop1Time2} = statistics(wall_clock),
>         io:format("Sent ~p messages in ~p /~p~n", [100000, Loop1Time1,
> Loop1Time2]),
>         statistics(runtime),
>         statistics(wall_clock),
>         PidLoop2 = spawn(?MODULE, loop2,[]),
>         sender(PidLoop2, 10000000),
>         {_, Loop2Time1} = statistics(runtime),
>         {_, Loop2Time2} = statistics(wall_clock),
>         io:format("Sent ~p messages in ~p /~p~n", [100000, Loop2Time1,
> Loop2Time2]).
>
> sender(_, 0) -> void;
> sender(Pid, N) ->
>         if
>           N rem 2 =:= 2 ->
>                 Pid ! test2;
>           true ->
>                 Pid ! test1
>         end,
>         sender(Pid, N - 1).
>
> proc1(F) ->
>         receive
>                 start -> spawn_link(F)
>         end.
>
> loop1() ->
>         receive
>                 %%test1 -> loop1();
>                 test2 -> loop1()
>         end.
>
> loop2() ->
>         receive
>                 _ -> loop2()
>         end.
>
>
> ------------------------------------------------------------------------------------------------------------------------------
> Message: 2
> Date: Fri, 30 May 2008 18:07:18 +0200
> From: "Per Melin" <>
> Subject: Re: [erlang-questions] eep: multiple patterns
> To: "Sean Hinde" <>
> Cc: Erlang Questions <>
> Message-ID:
>        <>
> Content-Type: text/plain; charset=ISO-8859-1
>
> 2008/5/30 Per Melin <>:
>> If I send 100k 'foo' messages and then 100k 'bar' messages to a
>> process, and then do a catch-all receive until there are no messages
>> left, that takes 0.03 seconds.
>>
>> If I do a selective receive of only the 'bar' messages, it takes 90
>> seconds.
>
> I found my old test code:
>
> -module(selective).
>
> -export([a/2, c/2]).
>
> a(Atom, N) ->
>    spawn(fun() -> b(Atom, N) end).
>
> b(Atom, N) ->
>    spam_me(foo, N),
>    spam_me(bar, N),
>    R = timer:tc(?MODULE, c, [Atom, N]),
>    io:format("TC: ~p~n", [R]).
>
> c(Atom, N) ->
>    receive
>        Atom -> c(Atom, N - 1)
>    after 0 ->
>        N
>    end.
>
> spam_me(Msg, Copies) ->
>    lists:foreach(fun(_) -> self() ! Msg end, lists:duplicate(Copies, 0)).
>
> ---
>
> 2> selective:a(bar, 100000).
> <0.38.0>
> TC: {124130689,0}
> 3> selective:a(foo, 100000).
> <0.40.0>
> TC: {23176,0}
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list