Erlang Mailing Lists

Author Message

<  Erlang questions mailing list  ~  Performance question

crd at inversenet.com
Posted: Thu Mar 25, 1999 5:49 pm Reply with quote
Guest
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?

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.

Craig




Post generated using Mail2Forum (http://m2f.sourceforge.net)
tobbe at serc.rmit.edu.au
Posted: Thu Mar 25, 1999 10:37 pm Reply with quote
Guest
> 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?

Well, first of all. If you want to store lots of data I recommend using
ets-tables, see the man-page for ets. They give you O(1) performance.
Also, under the user-contrib area you'll find an "efficient dynamically
expanding array package for heap-based storage". I haven't used it
myself but Ulf Wiger (ulf.wiger_at_etx.ericsson.se) can probably give you
details about the performance. See:

http://www.serc.rmit.edu.au/mirrors/ose_mirror/user.html#dynarray-1.0

Next, there have been problems (in the past at least) when you try to
compile a tuple of size > 256. The work around has been to create a
list of elements and then use the BIF list_to_tuple/1 .

Finally, yes if you don't modify your tuple. Erlang only passes
around the reference to it.

> Incidentally, why is there no recognizer guard for funs? ...

There is: function(F)

Cheers /Tobbe




Post generated using Mail2Forum (http://m2f.sourceforge.net)
klacke at erix.ericsson.s
Posted: Thu Mar 25, 1999 10:41 pm Reply with quote
Guest
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


Post generated using Mail2Forum (http://m2f.sourceforge.net)

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum