[erlang-questions] foldl vs foldr and ++

Andrew Ledvina wvvwwvw@REDACTED
Wed May 9 21:00:29 CEST 2012


Okay, so I was profiling something and it led me to write this:

 from_left(X) ->
   lists:foldl(fun(Y,R) -> R ++ [{Y+1,Y*2}] end, [], X).

 from_right(X) ->
   lists:foldr(fun(Y,R) -> [{Y+1,Y*2}] ++ R end, [], X).

 timeit(N) ->
   X = lists:seq(1,N),
   statistics(runtime),
   statistics(wall_clock),
   from_left(X),
   {_,LTime1} = statistics(runtime),
   {_,LTime2} = statistics(wall_clock),
   from_right(X),
   {_,RTime1} = statistics(runtime),
   {_,RTime2} = statistics(wall_clock),
   io:format("Left  runtime: ~p (~p)~n", [LTime1,LTime2]),
   io:format("Right runtime: ~p (~p)~n", [RTime1,RTime2]).

My understanding is that foldl is preferred over foldr because it is tail
recursive. I was also to understand that putting the accumulator on the
left-hand-side of the ++ operation is super bad. So, the following results
were a bit of a surprise at first:

 Erlang R14B01 (erts-5.8.2) [source] [smp:4:4] [rq:4] [async-threads:0]
[hipe] [kernel-poll:false]

 Eshell V5.8.2  (abort with ^G)
 1> listtime:timeit(10000).
 Left  runtime: 290 (286)
 Right runtime: 0 (1)
 ok
 2> listtime:timeit(100000).
 Left  runtime: 30670 (31011)
 Right runtime: 10 (13)
 ok

The times are in ms. 30 s versus 10 ms. The result of both functions
from_left and from_right are identical. Also, I am clearly aware that these
are both equivalent to just a more simple map. I think I understand the
results after a bit of a go around but is there anyone who has a simple,
clear explanation?

--Andrew Ledvina
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120509/4fd77be3/attachment.htm>


More information about the erlang-questions mailing list