Optimized Erlang alias functions

Let's say I have a function that is exported from a module, but modules reuse this function.

So, I wrote an alias because I am lazy when I code.

-export([get_toolkit/0]).

get_toolkit() -> 
    ... code ... code ... 
    ... code ... code ... 
    ... code ... code ... 
    {ok, Thing}.

tk() -> get_toolkit().

      

Does the compiler develop aliases?

thank

+3


source to share


3 answers


I think it will cost you one indirection. I say this because I took this code

-module(testit).
-export([get_toolkit/0, long/0, short/0]).

get_toolkit() -> 
    _ = lists:seq(1,100),
    {ok, thing}.

tk() -> 
   get_toolkit().

long() ->
    get_toolkit(),
    {ok, thing2}.

short() ->
    tk(),
    {ok, thing3}.

      

and generated ASM via erlc -S testit.erl which gave me

SNIP

{function, tk, 0, 4}.
  {label,3}.
    {line,[{location,"testit.erl",8}]}.
    {func_info,{atom,testit},{atom,tk},0}.
  {label,4}.
    {call_only,0,{f,2}}.


{function, long, 0, 6}.
  {label,5}.
    {line,[{location,"testit.erl",11}]}.
    {func_info,{atom,testit},{atom,long},0}.
  {label,6}.
    {allocate,0,0}.
    {line,[{location,"testit.erl",12}]}.
    {call,0,{f,2}}.
    {move,{literal,{ok,thing2}},{x,0}}.
    {deallocate,0}.
    return.


{function, short, 0, 8}.
  {label,7}.
    {line,[{location,"testit.erl",15}]}.
    {func_info,{atom,testit},{atom,short},0}.
  {label,8}.
    {allocate,0,0}.
    {line,[{location,"testit.erl",16}]}.
    {call,0,{f,4}}.
    {move,{literal,{ok,thing3}},{x,0}}.
    {deallocate,0}.
    return.

      



  • The first function specified in snip is the "short" function, tk / 0.
  • the second is a long function that calls get_toolkit / 0,
  • the third is a short function using the short hand tk / 0

ASM shows that the last function (the one using tk / 0) calls tk / 0 ({call, 0, {f, 4}}), which in turn calls get_toolkit / 0 ({call, 0, {e, 2}}). The function that uses get_toolkit / 0 calls get_toolkit / 0 ({call, 0, {f, 2}}) directly.

So, I believe no optimization is being applied.

Also, I did some timing tests that seemed to support this hypothesis;)

+5


source


(Can't comment, so include that in a supplementary answer ...)

Alternatively, you can tell the compiler to inline the function by adding:

-compile({inline,[tk/0]}).

      

that is

{function, get_toolkit, 0, 2}.
...
{function, tk, 0, 4}...
    {call_only,0,{f,2}}.
...
{function, short, 0, 8}...
    {call,0,{f,4}}.
...

      



will become

{function, get_toolkit, 0, 2}.
...
{function, short, 0, 6}...
    {call,0,{f,2}}.

      

which excludes the function entirely tk/0

since it was not exported and the inline code calls directly get_toolkit

.

This is documented in http://www.erlang.org/doc/man/compile.html , Attachment section .

+2


source


Depends on what you mean by optimization. Generally speaking, the compiler will optimize calls where it knows the names of modules and functions at runtime, especially if the function is in the same module, so I tend to say yes.

+1


source







All Articles