[erlang-questions] Efficiency is passing a functin

Jim Rosenblum jrosenblum@REDACTED
Sun Sep 23 15:45:02 CEST 2012


Ulf,

How do I reconcile your answer with the previous reference to: http://www.erlang.org/doc/efficiency_guide/functions.html#id67199  which seems to imply that Funs are significantly slower?


On Sep 23, 2012, at 8:55 AM, Ulf Wiger <ulf@REDACTED> wrote:

> 
> To begin with, your example won't compile, but the question is still valid.
> 
> Consider this program:
> 
> =================
> -module(foldtest).
> -export([f1/2, f2/2]).
> 
> f1(Acc, Lst) ->
>     F = fun(A,B) -> my_function(A,B) end,
>     lists:foldl(F, Acc, Lst).
> 
> f2(Acc, Lst) ->
>     lists:foldl(fun my_function/2, Acc, Lst).
> 
> my_function(X, Acc) ->
>     [X|Acc].
> =================
> 
> I believe this illustrates the question, but compiles and runs correctly.
> 
> Eshell V5.9  (abort with ^G)
> 1> foldtest:f1([], [1,2,3]).
> [3,2,1]
> 2> foldtest:f2([], [1,2,3]).
> [3,2,1]
> 
> Now, let's compile the code with `erlc -S foldtest.erl` (generating ASM code):
> 
> {function, f1, 2, 2}.
>   {label,1}.
>     {line,[{location,"foldtest.erl",4}]}.
>     {func_info,{atom,foldtest},{atom,f1},2}.
>   {label,2}.
>     {allocate,2,2}.
>     {move,{x,1},{y,0}}.
>     {move,{x,0},{y,1}}.
>     {make_fun2,{f,14},0,0,0}.
>     {move,{y,0},{x,2}}.
>     {move,{y,1},{x,1}}.
>     {line,[{location,"foldtest.erl",6}]}.
>     {call_ext_last,3,{extfunc,lists,foldl,3},2}.
> 
> 
> {function, f2, 2, 4}.
>   {label,3}.
>     {line,[{location,"foldtest.erl",9}]}.
>     {func_info,{atom,foldtest},{atom,f2},2}.
>   {label,4}.
>     {allocate,2,2}.
>     {move,{x,1},{y,0}}.
>     {move,{x,0},{y,1}}.
>     {make_fun2,{f,12},0,0,0}.
>     {move,{y,0},{x,2}}.
>     {move,{y,1},{x,1}}.
>     {line,[{location,"foldtest.erl",10}]}.
>     {call_ext_last,3,{extfunc,lists,foldl,3},2}.
> 
> As you can tell, the two alternatives generate identical code.
> 
> The fun is compiled into a regular function, albeit with a funny name, and calling it carries the same cost as calling a hand-written function. Actually instantiating a fun context carries a slight overhead depending on the number of variables that need to be imported into the context (in this case, zero). There will be one level of indirection in both cases.
> 
> BR,
> Ulf W
> 
> On 23 Sep 2012, at 02:07, James Rosenblum wrote:
> 
>> Is there an appreciable difference in these two ways of passing a function?
>> 
>> F = fun(A,B) -> my_function(A,B) end.
>> lists:map(F, Lst)
>> 
>> vs.
>> 
>> -export([my_function/2]).
>> 
>> lists:map(fun my_function/2, Lst)
> 
> Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
> http://feuerlabs.com
> 
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120923/eaa458dc/attachment.htm>


More information about the erlang-questions mailing list