Cost of call on Erlang

  • Erlang R14A (erts-5.8) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:true]
  • Linux suneo 2.6.32-23-generic #37-Ubuntu SMP Fri Jun 11 08:03:28 UTC 2010 x86_64 GNU/Linux

results

call 100,000 times.

call type msec
call fun0 7
call fun1 7
gen_server:call fun0 local 313
gen_server:call fun1 local 323
gen_server:call fun1_spawn local 568
gen_server:call fun0 remote 9970
gen_server:call fun1 remote 10587
gen_server:call fun1_spawn remote 12337
rpc:call fun0 13750
rpc:block_call fun0 12944

code

You can try the same benchmark with http://github.com/higepon/Erlang-cost-of-call .

test.erl
-module(test).
-export([start/0, test/0, get_remote_server/0]).

timeit(Msg, Fun, Ntimes) ->
    L = lists:seq(1, Ntimes),
    statistics(wall_clock),
    lists:foreach(fun(_) -> Fun() end, L),
    {_, Msec} = statistics(wall_clock),
    io:format("~.40s : ~p msec~n", [Msg, Msec]).

get_remote_server() ->
    {ok, Pid} = gen_server:start(test_server, [], []),
    Pid.

start() ->
    receive
        forever ->
            start()
    end.

test() ->
    Ntimes = 100000,
    {ok, Pid} = gen_server:start(test_server, [], []),
    RemotePid = rpc:call(list_to_atom("test1@127.0.0.1"), test, get_remote_server, []),
    timeit("call fun0", fun() -> test_server:fun0() end, Ntimes),
    timeit("call fun1", fun() -> test_server:fun1("Hello") end, Ntimes),
    timeit("gen_server:call fun0 local", fun() -> gen_server:call(Pid, fun0) end, Ntimes),
    timeit("gen_server:call fun1 local", fun() -> gen_server:call(Pid, {fun1, "Hello"}) end, Ntimes),
    timeit("gen_server:call fun1_spawn local", fun() -> gen_server:call(Pid, fun1_spawn) end, Ntimes),
    timeit("gen_server:call fun0 remote", fun() -> gen_server:call(RemotePid, fun0) end, Ntimes),
    timeit("gen_server:call fun1 remote", fun() -> gen_server:call(RemotePid, {fun1, "Hello"}) end, Ntimes),
    timeit("gen_server:call fun1_spawn remote", fun() -> gen_server:call(RemotePid, fun1_spawn) end, Ntimes),
    timeit("rpc:call fun0", fun() -> rpc:call(list_to_atom("test1@127.0.0.1"), test_server, fun0, []) end, Ntimes),
    timeit("rpc:block_call fun0", fun() -> rpc:block_call(list_to_atom("test1@127.0.0.1"), test_server, fun0, []) end, Ntimes),
    halt(0).
test_server.erl
-module(test_server).

-behaviour(gen_server).

-export([start_link/0, fun0/0, fun1/1, fun1_spawn/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-record(state, {}).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    {ok, #state{}}.

handle_call(fun0, _From, State) ->
    {reply, fun0(), State};

handle_call(fun1_spawn, From, State) ->
    spawn_link(test_server, fun1_spawn, [From]),
    {noreply, State};

handle_call({fun1, Arg}, _From, State) ->
    {reply, fun1(Arg), State};

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

fun0() ->
    true.

fun1(Arg) ->
    Arg.

fun1_spawn(From) ->
    gen_server:reply(From, ok).