list comprehension performance vs. map() and filter()

Jason Orendorff jason at jorendorff.com
Sun Dec 9 17:34:41 EST 2001


I read some code and ran some off-the-cuff benchmarks.
And the winner is... well, it depends.

map() and filter() pros:
 - Inner loop is C instead of Python bytecode.  (Negligible.)
 - map() predicts the size of the result list and allocates it
   all at once.  List comprehensions use list.append() instead.
 - map(F, L) only performs the name lookup for F once.
   [F(x) for x in L] puts the name lookup inside the loop.

List comprehension pros:
 - Better-looking
 - In many situations, using map() means writing a lambda.  The
   resulting loop, then, contains an additional function call.
   A list comprehension may compile to bytecode that doesn't
   perform any function calls at all.  This is good because
   function calls are relatively expensive in Python.

It looks like the last consideration is the most important.
If using map() means extra function calls, the list comprehension
wins.

Usual benchmark disclaimers apply.

Times given were measured using time.clock() on Win2000.
Smaller numbers indicate faster code.
Column 1: 10000 loops, len(L) == 100.
Column 2:   100 loops, len(L) == 10000.
Column 3:     1 loop,  len(L) == 1000000.

   ---1---  ---2---  ---3---
Test one-argument map()
     1.29     1.78     1.48 : map(lambda x: x%9*x, L)
     1.09     1.54     1.59 : [x%9*x for x in L]
     1.36     1.91     1.76 : map(F, L)
     2.01     2.48     2.73 : [F(x) for x in L]
Test one-argument filter()
     1.53     1.77     1.67 : filter(lambda x: x%7 == 1, L)
     0.80     1.05     0.98 : [x for x in L if x%7 == 1]
     1.75     1.90     1.79 : filter(P, L)
     1.74     1.89     1.87 : [x for x in L if P(x)]
Test map(F, filter(P, L))
     1.75     2.01     1.96 : map(lambda x: x%9*x, filter(lambda x: x%7 ==
1, L))
     0.86     1.12     1.07 : [x%9*x for x in L if x%7 == 1]
     2.02     2.13     2.02 : map(F, filter(P, L))
     1.95     2.12     2.07 : [F(x) for x in L if P(x)]
Test filter(P, map(F, L))
     2.84     3.47     3.29 : filter(lambda x: x%7 == 1, map(lambda x:
x%9*x, L))
     1.28     1.56     1.45 : [x%9*x for x in L if (x%9*x)%7 == 1]
     3.17     3.74     3.62 : filter(P, map(F, L))
     3.23     3.41     3.30 : [F(x) for x in L if P(F(x))]
Test two-argument map(F, L, L2)
     0.65     1.53     1.43 : map(add, L, L2)
     1.37    14.28    34.08 : [x+y for x, y in zip(L, L2)]

--
Jason Orendorff    http://www.jorendorff.com/





More information about the Python-list mailing list