OT? -NO! Essay: Programming as if Performance Mattered
Bjorn Gustavsson
bjorn@REDACTED
Fri May 7 10:42:03 CEST 2004
Peter-Henry Mander <erlang@REDACTED> writes:
> Hehe :-) how does it feel to be flamebait James?
>
> After reading the article, I had a poke around for myself, and found
> this in lists.erl (R9C) which made me curious:
>
> %% reverse(L) reverse all elements in the list L. Is now a BIF!
>
> reverse([] = L) ->
> L;
> reverse([_] = L) ->
> L;
> reverse([A, B]) ->
> [B, A];
> reverse([A, B | L]) ->
> lists:reverse(L, [B, A]).
>
> Is it a BIF, or is it not? What is the purpose of these four
> clauses? Surely the BIF should handle these cases, or is this a tweak
> for optimisation? How does Erlang know to call this definition of
> lists:reverse/1 in lists.erl instead of the BIF definition?
Actually, it is lists:reverse/2 that is a BIF. (The comment is somewhat
unclear.)
The definition of for reverse/1 used to be:
reverse(L) ->
lists:reverse(L, []).
but was changed to speed up reversal of short lists. Measurements show that
the four-clause reverse/1 indeed is faster, but trying to special-case
reverse more than 2 elements is slower than calling the BIF.
>
> Another thing in http://www.dadgum.com/james/shootout.html mentioned the
> cost of inter-module calls, where replacing lists:append/2 with ++.
> Surely this cost must be vanishingly small, specially if the module is
> loaded and ready to go?
Yes, inter-module calls are very cheap.
As James guessed in his article, code such as
"foo" ++ L
is rewritten by the compiler to
[$f,$o,$o|L]
while no similar optimization is done if you call lists:append/2.
/Bjorn
--
Björn Gustavsson, Erlang/OTP, Ericsson AB
More information about the erlang-questions
mailing list