lambda用法的性能问题

时间:2014-11-05 15:17:23

标签: python lambda

示例代码:

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)

对于上述两个例子,这两个例子之间有明显的区别。当列表(ll)足够大时,使用lambda的时间比另一个花费的时间多得多。

从我的观点来看,原因很清楚。因为lambda是匿名函数,并且函数的调用花费了很多时间,而不是我认为的语句。

并且使用lambda的建议是替换一些简单的函数。但是从上面的实验来看,表现很差。

2 个答案:

答案 0 :(得分:1)

您可以使用generator表达式执行此操作。这不会在内存中创建额外的列表。

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

如果我们比较时间

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

在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

答案 1 :(得分:1)

&#34;性能问题&#34;您所看到的与lambda <。<}完全无关。

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

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

完全等同于

与您的map表达相等的近似值

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

基本上,您在使用map时会在内存中构建另一个列表。


忽略此问题,请注意使用lambda 仍会有一些额外函数调用的开销。

如果您想保留lambda,可以使用itertools.imap来避免创建列表。 否则,Vishnu Upadhyay对生成器表达式的建议可能是最佳解决方案,因为它更具可读性具有更好的性能