Optimization of list comprehensions?

Ulf Wiger etxuwig@REDACTED
Tue Feb 6 10:43:07 CET 2001




On Mon, 5 Feb 2001, David Gould wrote:

>I really like list comprehensions, they seem so, declarative. I am
>tempted to use them everywhere ;-)

Yes, they're nice.


>But, what does the compiler do with them?
>
>Does it generate better code for a list comprehension than for using
>lists:map()?

Essentially, the list comprehension becomes a lists:map().


You can check for yourself by using the 'E' compiler option.
Here's an example:

*********************** lctest.erl

-module(lctest).
-author('etxuwig@REDACTED').

%%-compile(export_all).
-export([lc1/1,
         lc2/2]).


lc1(List) ->
    [foo(X) ||
        X <- List,
        X > 17].

lc2(List1, List2) ->
    [foo({X, Y}) || 
        X <- List1,
        Y <- List2,
        X > Y].

foo(X) -> X.


***********************

erlc -E lctest.erl


*********************** lctest.E


-author(['etxuwig@REDACTED']).

lc1(List) ->
    begin
        %0 = % fun-info:
{78720207,[['%0','%1','X'],['%0','%1'],['%0']],[]}
             fun ([X|%1],%0) ->
                     if
                         X > 17 ->
                             [foo(X)|%0(%1,%0)];
                         true ->
                             %0(%1,%0)
                     end;
                 ([_|%1],%0) ->
                     %0(%1,%0);
                 ([],%0) ->
                     [] end,
        %0(List,%0)
    end.

lc2(List1,List2) ->
    begin
        %2 = % fun-info:
{123483443,[['%2','%3','X'],['%2','%3'],['%2']],['List2
']}
             fun ([X|%3],%2) ->
                     begin
                         %4 = % fun-info:
{38130919,[['%4','%5','Y'],['%4','%5']
,['%4']],['%2','%3','X']}
                              fun ([Y|%5],%4) ->
                                      if
                                          X > Y ->
                                              [foo({X,Y})|%4(%5,%4)];
                                          true ->
                                              %4(%5,%4)
                                      end;
                                  ([_|%5],%4) ->
                                      %4(%5,%4);
                                  ([],%4) ->
                                      %2(%3,%2) end,
                         %4(List2,%4)
                     end;
                 ([_|%3],%2) ->
                     %2(%3,%2);
                 ([],%2) ->
                     [] end,
        %2(List1,%2)
    end.

foo(X) ->
    X.

module_info() ->
    [].

module_info(_) ->
    [].





>Is it able to detect when a listcomp is used for its side effects
>alone and not build the result?

I don't recall seeing anything like that in the compiler
(but I will admit I don't understand the compiler well enough to be
sure.)



>Oh yeah, is it better or worse style?


Personally, I try to avoid using list comprehensions when I really
don't care about the result, since lists:foreach/2 makes that point
very clearly. 

/Uffe
-- 
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB




More information about the erlang-questions mailing list