[erlang-questions] Efficiency is passing a functin

Ulf Wiger ulf@REDACTED
Sun Sep 23 14:55:49 CEST 2012


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/09a5c7de/attachment.htm>


More information about the erlang-questions mailing list