[erlang-questions] OTP process startup vs spawn overhead

Ulf Wiger ulf.wiger@REDACTED
Thu Jul 28 14:13:51 CEST 2011


On 28 Jul 2011, at 13:04, Heinrich Venter wrote:

> It also shows a bout 45% performance penalty for spawning OTP
> processes like mad instead of using spawn(Module, Function, Args).
> On the other hand using spawn(Fun) seems to be 4 times slower.  This
> is more or less in line with what the efficiency guide says.
> 
> It pays to measure :)

It's true that using proc_lib:spawn_link() (which is what the OTP behaviours do) does come with some overhead.  Specifically, some data is inserted into the process dictionary for debugging support, and a catch is put on the init function so that more informative crash reports can be produced.

We should also remember that raw spawn_link/3 is a very cheap function, so in absolute terms, even spawning OTP processes is a very cheap function. The overhead is a constant factor, and usually well worth it.

Then again, if you are writing a pmap, or some other code where minimising overhead is more important than good diagnostics, I agree that one shouldn't uncritically use OTP behaviours.

Still, I'm suspicious of the difference between spawn_link/1 and spawn_link/3. When I tried myself on R14B03, I saw no significant difference.

Here is the code I used:

-module(spf).
-export([t1/1, t2/1]).
-export([do_recv/0]).


t1(N) when N > 0 ->
    spawn_link(fun() ->
		       receive
			   _ ->
			       ok
		       end
	       end) ! ok,
    t1(N-1);
t1(0) ->
    ok.


t2(N) when N > 0 ->
    spawn_link(?MODULE, do_recv, []) ! ok,
    t1(N-1);
t2(0) ->
    ok.

do_recv() ->
    receive
	_ ->
	    ok
    end.

Sample shell output:

Eshell V5.8.4  (abort with ^G)
1> c(spf).
{ok,spf}
2> timer:tc(spf,t1,[10000]).
{68349,ok}
3> timer:tc(spf,t1,[10000]).
{71315,ok}
4> timer:tc(spf,t1,[10000]).
{68363,ok}
5> timer:tc(spf,t1,[10000]).
{70570,ok}
6> timer:tc(spf,t1,[10000]).
{73481,ok}
7> timer:tc(spf,t1,[10000]).
{68041,ok}
8> timer:tc(spf,t1,[10000]).
{79669,ok}
9> timer:tc(spf,t2,[10000]).
{68404,ok}
10> timer:tc(spf,t2,[10000]).
{64816,ok}
11> timer:tc(spf,t2,[10000]).
{70428,ok}
12> timer:tc(spf,t2,[10000]).
{74202,ok}

Running the commands too quickly is likely to pollute the measurement, since there is already a "tail" on each run.

BR,
Ulf W

Ulf Wiger, CTO, Erlang Solutions, Ltd.
http://erlang-solutions.com






More information about the erlang-questions mailing list