[erlang-questions] Blog: Erlang Fractal Benchmark

Ulf Wiger (TN/EAB) ulf.wiger@REDACTED
Mon Jun 4 18:18:40 CEST 2007


I ran it on my machine, which scored a miserable
4.2 seconds. Adding is_float/1 guards around all
variables that are floats (quite a few) and 
compiling with native brought it down to 1.8 secs.

My screen IO is really bad, since I use VNC over
an IPSec tunnel on ADSL, so I did a little 
optimization of the screen output as well.

Originally, you didn't have to call lists:map/2,
since you only called io:format/2, thus returning
'ok' in each iteration. lists:foreach/2 would have
done fine (not that it would have changed the 
timing much). But io:format/2 makes a synchronous
call to an IO server each time, so making plot/2
return a character, and using map to build a 
string, lets you call io:format() once for each
line instead of once per character. I messed up
the measurements in the end, so I don't know if
this was the cause of halving the wall_clock
time, which I observed, or whether it was 
something else.

Personally, when benchmarking stuff, I tend to 
run several times and pick the smallest value,
reasoning that the other timings included more
noise.

BR,
Ulf W

-module(fractal_benchmark).
-author("Jim Menard, jimm@REDACTED").
-export([run/0]).

-define(BAILOUT, 16).
-define(MAX_ITERATIONS, 1000).

%% Idea from http://www.timestretch.com/FractalBenchmark.html

run() ->
    io:format("Rendering~n"),
    statistics(runtime),
    statistics(wall_clock),
    Seq = lists:seq(-39,39),
    lists:foreach(fun(Y) ->
			  S = lists:map(fun(X) -> plot(X, Y) end, Seq),
			  io:format("~s~n", [S])
		  end, Seq),
    io:format("~n"),
    {_, Time1} = statistics(runtime),
    {_, Time2} = statistics(wall_clock),
    Sec1 = Time1 / 1000.0,
    Sec2 = Time2 / 1000.0,
    io:format("Erlang Elapsed ~p (runtime) ~p (wall clock) seconds~n",
              [Sec1, Sec2]).

plot(X, Y) ->
    case iterate(X/40.0, Y/40.0) of
        0 ->
	    42;  % ASCII for *
	_ ->
	    32   % ASCII for space
    end.

iterate(X, Y) 
  when is_float(X), is_float(Y) ->
    CR = Y - 0.5,
    CI = X,
    iter_value(CR, CI, 0.0, 0.0, 0.0, 0.0, 0).

iter_value(_, _, _, _, _, _, I) when I > ?MAX_ITERATIONS ->
    0;
iter_value(_, _, _, ZI2, _, ZR2, I)
  when is_float(ZI2), is_float(ZR2), ZI2 + ZR2 > ?BAILOUT ->
    I;
iter_value(CR, CI, ZI, ZI2, ZR, ZR2, I)
  when is_float(CR), is_float(ZI), is_float(ZI2), is_float(ZR),
is_float(ZR2) ->
    Temp = ZR * ZI,
    ZRnew = ZR2 - ZI2 + CR,
    ZInew = Temp + Temp + CI,
    iter_value(CR, CI, ZInew, ZInew * ZInew, ZRnew, ZRnew * ZRnew, I +
1). 

> -----Original Message-----
> From: erlang-questions-bounces@REDACTED 
> [mailto:erlang-questions-bounces@REDACTED] On Behalf Of Jim Menard
> Sent: den 4 juni 2007 14:34
> To: erlang-questions@REDACTED
> Subject: [erlang-questions] Blog: Erlang Fractal Benchmark
> 
> I've just posted "Erlang Fractal Benchmark" at 
> http://jimmenard.blogspot.com/2007/06/erlang-fractal-benchmark.html.
> Any comments on the code are much appreciated.
> 
> Jim
> --
> Jim Menard, jimm@REDACTED, jim.menard@REDACTED 
> http://www.io.com/~jimm/ 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
> 



More information about the erlang-questions mailing list