0

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.

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

This is why you can't trust your intuition for optimizing.
in addition, there is some function call overhead from the lambda vs just evaluating the expression in the for loop
I didn't use timeit, but i use cProfile to profile the time consumption of these two implementation in my example code. even though the above code is not exactly equal, but in cProfile profiling result, the function created by lambda cost most time when ll is long enough. @Vishnu Upadhyay 's suggestion is a good replacement
1

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

5 Comments

Did you do the timing test with Python 3?
yes. using the generator expression has the better performance because it doesn't have a function call overhead.
@gg_fei check the updated code for python3. generators are faster because here its are expression while in map & lambda make it little slower then generator.
@VishnuUpadhyay Yes. I agree about expression is much faster than map & lambda. That's also what I want to express, map & lambda slower than the expression. Additionally, I want to say we should't use lambda in most cases. Each time call to lambda anonymous function have function call overhead.
@gg_fei i am just trying to tell it by showing output, please mark correct if you get it as right answer. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.