[erlang-questions] OTP Efficiency

Ulf Wiger <>
Thu Jun 3 10:41:18 CEST 2010


Max Lapshin wrote:
> I've also tried to work without OTP and there have been left only two
> places in my code, which are not OTP:
> 
> 1) gen_server:call changed to implementation without additional
> erlang:monitor, because caller already has monitor.
> It reduced load.

Note, however, that a new optimization in the OTP "dev" branch
makes selective message reception O(1), i.e. insensitive to the
length of the message queue - given that it can be determined at
compile-time that the receive patterns can not match any message
received before a certain time.

The way to achieve this is to create a unique reference (make_ref/1
or monitor/2), and then use that reference in each receive clause,
e.g.

call(P, Req, T) ->
    Ref = erlang:monitor(process, P),
    P ! {'$req', {self(), Ref}, Req},
    receive
       {Ref, Reply} ->
          Reply;
       {'DOWN', Ref, _, _, Reason} ->
          erlang:error(Reason, [P, Req, T])
    after T ->
       erlang:error(timeout, [P, Req, T])
    end.

My guess (not having dug into the code to verify) is that
you can substitute a call to make_ref() for the monitor
call, but a pre-existing monitor ref would not suffice.

What the compiler does is basically transform it into this:

call(P, Req, T) ->
    Ref = erlang:monitor(process, P),
    <recv_mark>
    P ! {'$req', {self(), Ref}, Req},
    <recv_set>
    receive
       {Ref, Reply} ->
          Reply;
       {'DOWN', Ref, _, _, Reason} ->
          erlang:error(Reason, [P, Req, T])
    after T ->
          erlang:error(timeout, [P, Req, T])
    end.

...but at the BEAM ASM level, where <recv_mark> and
<recv_set> are new instructions, marking the end of the
message queue, and then jumping to that mark and doing
the receive processing from there.

In other words, removing the monitor may not in all cases
result in faster code. It could well be the other way around.

The gen:call() function has been refactored to make this
compiler optimization possible (i.e. await_reply() has been
inlined.)

This is in some sense indicative of how the OTP team approaches
optimizations. They tend to focus on changes that make "textbook"
Erlang run faster, rather than going for impressive benchmark
performance. They are a bit boring that way, but it is a very
good reason to stick to the "mainstream" way of coding.

BR,
Ulf W
-- 
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
---------------------------------------------------

---------------------------------------------------

WE'VE CHANGED NAMES!

Since January 1st 2010 Erlang Training and Consulting Ltd. has become ERLANG SOLUTIONS LTD.

www.erlang-solutions.com



More information about the erlang-questions mailing list