Performance question

Claes Wikstrom <>
Thu Mar 25 23:41:29 CET 1999



Craig Dickson writes:
 > I have an algorithm which requires a recursive function to have access to a
 > fairly large fixed-size array of constants (probably a tuple, indexable with
 > element/2 since that should have O(1) performance, and it won't need to be
 > anywhere near 64k elements long). My question is, if I simply declare this
 > tuple as a value within the function, will it be recreated for each
 > recursive call to the function, or is Erlang smart enough to set it up once
 > (at compile time, even, as pre-initialized static data, since it is never
 > modified) and keep it around for subsequent usage? Would it make any
 > difference if the tuple was passed in as an argument?


No the current compiler(s), neither jam nor beam does anything
particularly inteligent with code like:

f(0) ->
   ok;
f(I) ->
   test(I),
   f(I-1).

test(I) ->
   T = {x,f,t,y, ........ huge tuple ...}
   dosomething(T, element(T, I)).

T will be rebuilt every loop, this is very costly. We'd better write 
the code as:

f(I) ->
   f(I, {x,f,t,y, ........ huge tuple ...}).
f(0, _) ->
   ok;
f(I, T) ->
   test(I, T),
   f(I-1, T).

test(I, T) ->
   dosomething(T, element(T, I)).

Now T will only be built once. This absoluteley acceptable since it
is what would be typically  expected. 

 > 
 > Incidentally, why is there no recognizer guard for funs? If you don't mind
 > having your code assume that a fun is a certain type of record, you can use
 > record/2, but I don't recall the standard saying that funs had to be
 > implemented as records, so I'm not comfortable with that.

There is, the guard test function(F) exists, with a little quirk
though. First:

test() ->
    a(fun(X) ->  X end).

a(F) when function(F) ->
    function;
a(F) when list(F) ->
    list.


returns the atom 'function', however, and this actually sucks a bit
Funs today are tuples, try out 

1> tuple_to_list(fun(X) -> X end)

and cry.

Hopefully this will be fixed real soon.

So, 

test2() ->
    b(fun(X) ->  X end).
b(F) when tuple(F) ->
    tuple;
b(F) when function(F) ->
    F.


actually returns the atom 'tuple'.

This is no big deal in real life since we only have to test for 
functions before tuples if we want to discriminate on types
in clause mathing.


Cheers

/klacke



More information about the erlang-questions mailing list