[erlang-questions] Blog: Erlang Fractal Benchmark

Ulf Wiger ulf@REDACTED
Tue Jun 5 09:12:53 CEST 2007


It seems counter-intuitive at first, doesn't it? (:
Adding checking to the code shouldn't speed things up,
but the thing is that, being dynamically typed, Erlang will
have to do type checking in all the multiplications, etc,
checking first the operands, and then the result.

But if the compiler can deduce (because of the guards)
what the type signature is, it can generate much more
efficient code, foregoing redundant type checks.

I think(*) it's pretty much generally true that adding type
guards never slows things down, but adds compile-time
info that can be used by Dialyzer as well as in some
optimizations.

(*) This is to say that I'm guessing this is the case. It _seems_ true.

BR,
Ulf W

2007/6/5, Jim Menard <jim.menard@REDACTED>:
>
> On 6/4/07, Ulf Wiger (TN/EAB) <ulf.wiger@REDACTED> wrote:
> >
> > 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.
>
> It sped up my version considerably as well. Why is that? I thought
> that a guard clause was only used to select which function clause to
> run. How does checking to see if something is a float make things
> faster instead of slowing it down by having to execute is_float/1 for
> each call?
>
> >
> > 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
> > >
> >
>
>
> --
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070605/f8c55f50/attachment.htm>


More information about the erlang-questions mailing list