[erlang-questions] flash clauses vs nested clauses

Pablo Platt pablo.platt@REDACTED
Fri Apr 6 18:19:21 CEST 2012


Thank you Jachym for the top about erlc -S
and Joe for the excellent explanation.




----- Original Message -----
From: Joe Armstrong <erlang@REDACTED>
To: Pablo Platt <pablo.platt@REDACTED>
Cc: Erlang <erlang-questions@REDACTED>
Sent: Friday, April 6, 2012 2:41 PM
Subject: Re: [erlang-questions] flash clauses vs nested clauses

On Thu, Apr 5, 2012 at 5:22 PM, Pablo Platt <pablo.platt@REDACTED> wrote:
> Hi,
>
> Is there a difference in performance between using nested clauses and flat clauses
> or is the compiler smart enough to produce the same optimizations?

It's smart :-)

If you take the first code and compile with erlc -S you'll see that I mean.

If we compile:

somefun(a1, b1, c1) ->
    res1;
somefun(a1, b1, c2) ->
    res2;
somefun(a1, b1, c3) ->
    res3;
somefun(a1, b2, c1) ->
    res4;
somefun(a1, b2, c2) ->
    res5;
somefun(a2, b1, c1) ->
    res6;
somefun(a2, b1, c2) ->
    res7.

The generated code is
{function, somefun, 3, 2}.
  {label,1}.
    {line,[{location,"try1.erl",4}]}.
    {func_info,{atom,try1},{atom,somefun},3}.
  {label,2}.
    {test,is_atom,{f,1},[{x,0}]}.
    {select_val,{x,0},{f,1},{list,[{atom,a2},{f,3},{atom,a1},{f,6}]}}.
       <======= Look at this
  {label,3}.
    {test,is_eq_exact,{f,1},[{x,1},{atom,b1}]}.
    {test,is_atom,{f,1},[{x,2}]}.
    {select_val,{x,2},{f,1},{list,[{atom,c2},{f,4},{atom,c1},{f,5}]}}.
   ... etc


The important line is

{select_val,{x,0},{f,1},{list,[{atom,a2},{f,3},{atom,a1},{f,6}]}}.

Which means if the first argument of the function is is a2 jump to label
3 or if it's a1 jump to label 6 - and this in turn is essentially what
the second
form of the code is. The a1 value is only tested once.

The beam loader will in turn this into some efficient
code when it is loaded.

In general the pattern matching compiler tries to produce an optimal
decision tree from the set of patterns you give it. Trying to outguess the
compiler is a waste of effort. Your should always aim for the code that
expresses your intent as clearly as possible.

Optimisation is usually best performed by changing the algorithms and
not messing
with the details of exactly how the pattern matching works.

Even if there were to be a in performance between the two methods
you chose you could never guarantee that this would persist into the future
the compiler could be changed in the future in a way that reversed your results.

/Joe



>
> For example:
>
> somefun(a1, b1, c1) ->
>     res1;
> somefun(a1, b1, c2) ->
>     res2;
> somefun(a1, b1, c3) ->
>     res3;
> somefun(a1, b2, c1) ->
>     res4;
> somefun(a1, b2, c2) ->
>     res5;
> somefun(a2, b1, c1) ->
>     res6;
> somefun(a2, b1, c2) ->
>     res7;
> ...
> somefun(a10, b10, c10) ->
>     res10.
>
>
> and
>
> somefun(a1, B, C) ->
>     case B of
>         b1 ->
>             case C of
>                 c1 -> res1;
>
>                 c2 -> res2;
>
>                 c3 -> res3
>
>             end;
>         b2 ->
>             case C of
>                 C1 -> res4;
>
>                 C2 -> res5
>             end
>
>      end;
> somefun(a2, B, C) ->
>     ...
>
> Thanks
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list