Okay, so I was profiling something and it led me to write this:<div><br></div><div><div> from_left(X) -></div><div> lists:foldl(fun(Y,R) -> R ++ [{Y+1,Y*2}] end, [], X).</div><div><br></div><div> from_right(X) -></div>
<div> lists:foldr(fun(Y,R) -> [{Y+1,Y*2}] ++ R end, [], X).</div><div><br></div><div> timeit(N) -></div><div> X = lists:seq(1,N),</div><div> statistics(runtime),</div><div> statistics(wall_clock),</div><div>
from_left(X),</div><div> {_,LTime1} = statistics(runtime),</div><div> {_,LTime2} = statistics(wall_clock),</div><div> from_right(X),</div><div> {_,RTime1} = statistics(runtime),</div><div> {_,RTime2} = statistics(wall_clock),</div>
<div> io:format("Left runtime: ~p (~p)~n", [LTime1,LTime2]),</div><div> io:format("Right runtime: ~p (~p)~n", [RTime1,RTime2]).</div></div><div><br></div><div>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:</div>
<div><br></div><div><div> Erlang R14B01 (erts-5.8.2) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]</div><div><br></div><div> Eshell V5.8.2 (abort with ^G) </div><div> 1> listtime:timeit(10000).</div>
<div> Left runtime: 290 (286)</div><div> Right runtime: 0 (1) </div><div> ok</div><div> 2> listtime:timeit(100000).</div><div> Left runtime: 30670 (31011)</div><div> Right runtime: 10 (13)</div><div> ok</div></div><div>
<br></div><div>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?</div>
<div><br></div><div>--Andrew Ledvina</div>