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