[erlang-questions] Erlang receive / after performance strangeness

Mikael Pettersson mikpe@REDACTED
Fri Jul 3 00:09:57 CEST 2009


Evans, Matthew writes:
 > Hi,
 > 
 > This is interesting, not sure if it is expected or not.
 > 
 > Two functions below.
 > 
 > One WITH the timer on the receive loop:
 > 
 > get_asset_data(ProcessId, Offset, Misc) ->
 >     ProcessId ! {get_asset_data, self(), Offset, Misc},
 >     receive
 >         Data -> Data
 >     after 2000 ->
 >         {error, []}
 >     end.
 > 
 > 
 > One WITHOUT the timer on the receive loop:
 > 
 > get_asset_data(ProcessId, Offset, Misc) ->
 >     ProcessId ! {get_asset_data, self(), Offset, Misc},
 >     receive
 >         Data -> Data
 >     end.
 > 
 > When running on a VM the one WITH the timer gets about 9500 messages per second. The one WITHOUT gets 15000 messages per second.
 > 
 > That's quite a performance drop (this is on a VM, running version 12B).
 > 
 > Is that expected?

Some performance drop can be expected from using 'after' since whenever
the receive blocks, it has to perform additional work to set up a timer,
and timers aren't cheap. And assuming a reply is received in time, the
timer has to be cancelled, and that's also an overhead.

And your !/receive combo looks like it will always have to block waiting
for ProcessId to do its thing, so you'll always incur the timer overhead.

What you're doing here is a blocking RPC. A more Erlangy way of doing
things is to have multiple pending asynchronous requests, and to have
some loop that both generates new requests and receives replies to pending
requests. That way delays in replies don't block other work.


More information about the erlang-questions mailing list