gg_fei
gg_fei

Reputation: 3

performance issue for lambda usage

example code:

def var1(ll):
  s = sum(ll)
  l = len(ll)
  ave = float(s) / l
  s = 0
  for v in ll:
    s += (v - ave) * (v - ave)
  return math.sqrt(s/l)

def var2(ll):
  s = sum(ll)
  l = len(ll)
  ave = float(s) / l
  s = sum(map(lambda v: (v - ave) * (v - ave), ll))
  return math.sqrt(s/l)

for above two examples, there is an obvious difference between these two examples. The one use lambda cost much more time than another when the list (ll) is large enough.

from my view, the cause is clear. because lambda is anonymous function and the invocation of the function cost much time then a statement I think.

and a suggestion for using lambda is to replace some simple function. but from the experiment above, the performance is bad.

Upvotes: 0

Views: 325

Answers (2)

Vishnu Upadhyay
Vishnu Upadhyay

Reputation: 5061

You can do it using a generator expression.this wouldn't create an extra list in memory.

sum((v-ave)**2 for v in ll) 

if we compare the time then

In [20]: %timeit sum(map(lambda v: (v - ave) * (v - ave), ll))
10 loops, best of 3: 27.7 ms per loop

In [21]: %timeit sum((v-ave)**2 for v in ll)
10 loops, best of 3: 23.8 ms per loop

in python3:-

In [9]:  %timeit sum((v-ave)**2 for v in ll)
10 loops, best of 3: 29.7 ms per loop

In [10]: %timeit sum(map(lambda v: (v - ave) * (v - ave), ll))
10 loops, best of 3: 33.5 ms per loop

Upvotes: 1

loopbackbee
loopbackbee

Reputation: 23322

The "performance issue" you're seeing is not entirely related to your lambda.

  for v in ll:
    s += (v - ave) * (v - ave)

s = sum(map(lambda v: (v - ave) * (v - ave), ll))

These are not equivalent at all.

A closer equivalent to that your map expresses would be

temporary_list=[]
for v in ll:
    temporary_list.append( (v - ave) * (v - ave) )
s= sum(temporary_list)

Basically, you're building another list in memory when using map.


Ignoring this issue, note that using a lambda will still have some overhead, in the form of extra function calls.

If you want to keep your lambda, you could use itertools.imap to avoid creating the list. Otherwise, Vishnu Upadhyay's suggestion of a generator expression is probably the best solution, since it's more readable and has better performance

Upvotes: 1

Related Questions