[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