[erlang-questions] Another erlang performance test ¿Who needs a lot of heap space?

Angel Alvarez <>
Wed Dec 23 15:00:33 CET 2009


ive attached a quick mod of ehttpd.erl (its named ehttpd2)
just printing process_info one the acceptors...

it seems that is far from the 80k....

:~/Documents/Personal/Erlang/Code> erl
Erlang R13B03 (erts-5.7.4) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> ehttpd2:start().
ehttpd ready with 1 schedulers on port 8888
Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,233},{heap_size,233},{stack_size,3},{reductions,3},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},{suspending,[]}]

Just a few hit from the broser the acceptor seems to no use more memory...


Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>,#Port<0.515>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,754},{heap_size,377},{stack_size,3},{reductions,429},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,2}]},{suspending,[]}]
Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>,#Port<0.516>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,754},{heap_size,377},{stack_size,3},{reductions,635},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,3}]},{suspending,[]}]
Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>,#Port<0.517>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,754},{heap_size,377},{stack_size,3},{reductions,840},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,4}]},{suspending,[]}]
Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>,#Port<0.518>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,754},{heap_size,377},{stack_size,3},{reductions,1058},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,6}]},{suspending,[]}]
Acceptor (1):
Memory Info:
[{registered_name,acceptor_1},{current_function,{ehttpd2,accept,2}},{initial_call,{ehttpd2,accept,2}},{status,running},{message_queue_len,0},{messages,[]},{links,[<0.33.0>,#Port<0.519>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.26.0>},{total_heap_size,754},{heap_size,377},{stack_size,3},{reductions,1263},{garbage_collection,[{fullsweep_after,65535},{minor_gcs,7}]},{suspending,[]}]

Still i dont know how the workers will do but when measuring againts 100 or more process the continous copying
of 80k of mostly unused heaps is not fair to compare againts a optimzed matured nginx. The more concurrency you 
add more overhead on the erlang side...

Why slow down erlang with useless oversized heaps? Just to keep java on the trends? :-P 
or helping the Go "monster Mix of paradigms"...

Still erlang rules...

      
El Miércoles, 23 de Diciembre de 2009 litao cheng escribió:
> hi Angel Alvarez, yes I also think the 80 K is too big.
> I hope someone will give us some high performance principles.
> :)
> 
> On Wed, Dec 23, 2009 at 9:04 PM, Angel Alvarez <> wrote:
> 
> > El Miércoles, 23 de Diciembre de 2009 litao cheng escribió:
> > > the author use +h 99999 just for that benchmark. it's set the min heap
> > size
> > > for process, with this option
> > > the http process will not involve garbage collect, so the performance
> > will
> > > be more satisfied. that's all.
> > > you can also use +h 88888, this heap size for that simple http echo
> > process
> > > is enough.
> > ~80 K for a process stil is overkill. Erlang procceses can be very
> > ligthweigth. I dont know but ill try to see whts's the bare minimun
> > for an acceptor loop. I thinks around 16k is still more than needed....
> >
> > Any erlang gurus can enligthen us?
> >
> > I put the code here just for brevity (Seems to use some starge patch)
> >
> > -module(ehttpd).
> >  -compile(export_all).
> > start() ->
> >  start(8888).
> >  start(Port) ->
> >  N = erlang:system_info(schedulers),
> >  listen(Port, N),
> >  io:format(”ehttpd ready with ~b schedulers on port ~b~n”, [N, Port]),
> >  register(?MODULE, self()),
> >  receive Any -> io:format(”~p~n”, [Any]) end. %% to stop: ehttpd!stop.
> > listen(Port, N) ->
> >  Opts = [{active, false},
> >  binary,
> >  {backlog, 256},
> >  {packet, http_bin},
> >  {raw,6,9,<<1:32/native>>}, %defer accept
> >  %%{delay_send,true},
> >  %%{nodelay,true},
> >  {reuseaddr, true}],
> >  {ok, S} = gen_tcp:listen(Port, Opts),
> >  Spawn = fun(I) ->
> >  register(list_to_atom(”acceptor_” ++ integer_to_list(I)),
> >  spawn_opt(?MODULE, accept, [S, I], [link, {scheduler, I}]))
> >  end,
> >  lists:foreach(Spawn, lists:seq(1, N)).
> > accept(S, I) ->
> >  case gen_tcp:accept(S) of
> >  {ok, Socket} -> spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]);
> >  Error -> erlang:error(Error)
> >  end,
> >  accept(S, I).
> > loop(S) ->
> >  case gen_tcp:recv(S, 0) of
> >  {ok, http_eoh} ->
> >  Response = <<"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello
> > world!">>,
> >  gen_tcp:send(S, Response),
> >  gen_tcp:close(S),
> >  ok;
> >  {ok, _Data} ->
> >  loop(S);
> >  Error ->
> >  Error
> >  end.
> > >
> > > Best Regards
> > > litao cheng
> > >
> > > On Wed, Dec 23, 2009 at 8:04 PM, Angel Alvarez <> wrote:
> > >
> > > > Hi lists
> > > >
> > > > ive just found
> > > >
> > > > http://timyang.net/programming/c-erlang-java-performance/
> > > >
> > > >
> > > >
> > > > this guy tried the erlang test with:
> > > >
> > > > erl +K true +h 99999 +P 99999 -smp enable +S 2:1 -s ehttpd
> > > >
> > > > Still erlang shines IMHO versus java or Go but i think +h 99999 is far
> > from
> > > > correct
> > > >
> > > > Who needs 99999 bytes of heap just for return a simple hello word http
> > > > result?
> > > >
> > > > On 1 CPU i think erlang would be faster with a more conservative heap.
> > (Now
> > > > He is just measuring unused heap copy back and forth..)
> > > >
> > > > Waht dou you think ?
> > > >
> > > >
> > > >
> > > > --
> > > > No imprima este correo si no es necesario. El medio ambiente está en
> > > > nuestras manos.
> > > > __________________________________________
> > > >
> > > > Clist UAH a.k.a Angel
> > > > __________________________________________
> > > > Artista -- (internet) --> Usuario final. Así los artistas cobran más y
> > > > dicen menos paridas sobre lo que creen que es la piratería.
> > > >
> > > > ________________________________________________________________
> > > > erlang-questions mailing list. See http://www.erlang.org/faq.html
> > > > erlang-questions (at) erlang.org
> > > >
> > > >
> > >
> >
> >
> >
> > --
> > No imprima este correo si no es necesario. El medio ambiente está en
> > nuestras manos.
> > __________________________________________
> >
> > Clist UAH a.k.a Angel
> > __________________________________________
> > If debugging is the process of removing bugs, then programming must be the
> > process of putting them in. Dijkstra.
> >
> 



-- 
Agua para todo? No, Agua para Todos.
->>-----------------------------------------------
    Clist UAH a.k.a Angel
---------------------------------[www.uah.es]-<<--

No le daría Cocacola Zero, ni a mi peor enemigo. Para eso está el gas Mostaza que es mas piadoso.
-------------- next part --------------
-module(ehttpd2).
-compile(export_all).

start() ->
	start(8888).
start(Port) ->
	N = erlang:system_info(schedulers),
	listen(Port, N),
	io:format("ehttpd ready with ~b schedulers on port ~b~n", [N, Port]),
	register(?MODULE, self()),
	receive 
		Any -> 
			io:format("~p~n", [Any]) 
	end. %% to stop: ehttpd!stop.

listen(Port, N) ->
	Opts = [{active, false},
		binary,
		{backlog, 256},
		{packet, http_bin},
		{raw,6,9,<<1:32/native>>}, %defer accept
		%%{delay_send,true},
		%%{nodelay,true},
		{reuseaddr, true}],
	{ok, S} = gen_tcp:listen(Port, Opts),
	Spawn = fun(I) ->
		register(list_to_atom("acceptor_" ++ integer_to_list(I)),
		spawn_opt(?MODULE, accept, [S, I], [link, {scheduler, I}]))
		end,
	lists:foreach(Spawn, lists:seq(1, N)).

accept(S, I) ->
	io:format("Acceptor (~w):~nMemory Info:~n~w~n", [I,erlang:process_info(self())]),
	case gen_tcp:accept(S) of
	{ok, Socket} -> 
		spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]);
	Error -> erlang:error(Error)
	end,
	accept(S, I).

loop(S) ->
	case gen_tcp:recv(S, 0) of
	{ok, http_eoh} ->
		Response = <<"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world!">>,
		gen_tcp:send(S, Response),
		gen_tcp:close(S),
		ok;
	{ok, _Data} ->
		loop(S);
	Error ->
		Error
	end.


More information about the erlang-questions mailing list