[Shootout-list] Re: Erlang Crisis! :-)

Einar Karttunen ekarttun@cs.helsinki.fi
Mon, 14 Jun 2004 11:40:18 +0300


This is a MIME-formatted message.  If you see this text it means that your
E-mail software does not support MIME-formatted messages.

--=_courier-3146-1087202419-0001-2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On 13.06 23:53, Brent A. Fulgham wrote:
> For some reason, Erlang has absolutely terrible performance on heapsort, 
> statistical moments, and interestingly even the producer/consumer 
> threads implementation (an area I would have expected to be strong).
> 
> Can some smart Erlang developers comment on why things look so bad?  
> I've seen real-world Erlang programs run with much better performance 
> than I would expect from these benchmarks.

Erlang is a functional language, which means there is no mutation. In 
real world apps this is rarely a problem, but it makes things quite
"interesting" with benchmarks like this.

setelement takes a tuple and produces a new tuple, so it is of course 
much slower than anything using inplace mutation for large tuples.
In real situations this is not really an issue as the fundamental 
model of programming is quite different. e.g. the erlang array
tests actually use an in-memory database which can be accessed
by multiple processes...


The producer/consumer just demonstrates the classic "why is a protocoll 
with window size of 1 slow", phenomenon. It is still two times faster
than the C version using mutexes ;) With a 10 times larger N (1000000)
the erlang version is about ten times faster than C... (see the attached
file). Note that the cvs version has two tiny bugs which make it hang 
(s/prodcon/prodcons in the spawn).

--- prodcons/prodcons.erlang    2004-06-14 10:07:10.000000000 +0300
+++ /home/e/shootout/orig/prodcons.erl  2004-06-14 11:24:06.000000000 +0300
@@ -33,8 +33,8 @@
 
 main([Arg]) ->
     N = list_to_integer(atom_to_list(Arg)),
-    P = spawn(prodcon, producer, [N, 0, self()]),     %% spawn producer thread
-    C = spawn(prodcon, consumer, [N, 0, P, self()]),  %% spawn consumer thread
+    P = spawn(prodcons, producer, [N, 0, self()]),     %% spawn producer thread
+    C = spawn(prodcons, consumer, [N, 0, P, self()]),  %% spawn consumer thread
     receive {P, NP} -> ok end,                        %% wait on producer thread
     receive {C, NC} -> ok end,                        %% wait on consumer thread
     io:format("~s ~w ~s ~w~n", ["Produced:", NP, "Consumed:", NC]),




Erlang startup is quite slow because it initializes the virtual 
machine for all kinds of operation and spawns multiple erlang 
server processes. For fast startup there is stand alone erlang
which produces executables suitable for command line use, however
building sae is not trivial and most people use the binary 
distribution if they have a need for it.

One could shave a little bit of the times by using erlexec directly
instead of the erl shell script. A much better speedup would result 
from using a dedicated boot script, but I don't know whether that
would be fair. When starting the erlang runtime loads a boot script
and loads all modules specified there and starts servers as specified 
there. The default boot file starts 30 processes and loads 100+ 
modules. Out of these the tests use < 5%.


btw hipe compile could use optimizing flags like most other 
languages do...

e@rei:~/shootout/shootout/bench$ cvs diff -u Makefile.mb 
Index: Makefile.mb
===================================================================
RCS file: /cvsroot/shootout/shootout/bench/Makefile.mb,v
retrieving revision 1.11
diff -u -r1.11 Makefile.mb
--- Makefile.mb 12 Jun 2004 16:19:43 -0000      1.11
+++ Makefile.mb 14 Jun 2004 07:31:24 -0000
@@ -132,7 +132,7 @@
 %.hipe_run: $(MB_SRCDIR)/%.hipe $(ERLC)
        -rm $(TEST).beam
        cp $< $(TEST).erl
-       $(ERLC) +native $(TEST).erl
+       $(ERLC) +native +"{hipe, [o3]}" $(TEST).erl
        touch $@
 
 ########################################


- Einar Karttunen

--=_courier-3146-1087202419-0001-2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="bench.txt"

e@rei:~/shootout/orig$ time erl -noinput -s prodcons main 1
Produced: 1 Consumed: 1

real    0m0.121s
user    0m0.110s
sys     0m0.010s
e@rei:~/shootout/orig$ time ./prodcons.gcc 1
1 1

real    0m0.002s
user    0m0.000s
sys     0m0.001s
e@rei:~/shootout/orig$ time erl -noinput -s prodcons main 100000
Produced: 100000 Consumed: 100000

real    0m0.178s
user    0m0.160s
sys     0m0.015s
e@rei:~/shootout/orig$ time ./prodcons.gcc 100000
100000 100000

real    0m0.516s
user    0m0.065s
sys     0m0.232s
e@rei:~/shootout/orig$ time erl -noinput -s prodcons main 1000000
Produced: 1000000 Consumed: 1000000

real    0m0.659s
user    0m0.640s
sys     0m0.016s
e@rei:~/shootout/orig$ time ./prodcons.gcc 1000000
1000000 1000000

real    0m4.537s
user    0m0.637s
sys     0m1.781s
e@rei:~/shootout/orig$ 

--=_courier-3146-1087202419-0001-2--