[erlang-questions] Erlang arithmetics

Jachym Holecek <>
Sat Oct 30 17:31:50 CEST 2010


Hello,

This one:

   -module(b).
   -export([test/1]).

   test(N) ->
       L = [random_point(1000, 1000) || _ <- lists:seq(1, N)],
       Now = now(),
       distance(L, 0.0),
       timer:now_diff(now(), Now).

   distance([{X0, Y0} | [{X1, Y1} | _] = L], Acc) ->
       Dst = math:sqrt(square(X0 - X1) + square(Y0 - Y1)),
       distance(L, Dst + Acc);
   distance([_], Acc) ->
       Acc.

   square(X) ->
       X * X.

   random_point(Xmax, Ymax) ->
       {random:uniform(Xmax), random:uniform(Ymax)}.

is a bit faster than your original version (and maybe a bit easier on
beginner's eyes):

   %% 'a' -- original, 'b' -- the above, results from 6 consecutive runs.
   a:test(1000000) => [288317, 324549, 327840, 386648, 388363, 390389]
   b:test(1000000) => [210855, 230395, 238020, 246694, 253710, 261157]

Speedup may be because 'b' avoids a little allocation overhead, ie. building
the lists:foldl/3 accumulator tuple. The floating point value used as Acc in
case 'b' will still be an on-heap object though -- compiler can unbox floats
locally, but not across function calls it seems? You're right in that integer
arith ops have to check for smallint -> bigint overflow, BTW.

I don't have Node.js or HiPE around for comparison...

Have fun,
	-- Jachym


More information about the erlang-questions mailing list