我正在将 any()
内置函数的性能与实际实现 docs 进行比较建议:
我在下面的列表中寻找一个大于 0 的元素:
lst = [0 for _ in range(1000000)] + [1]
这是假定的等效函数:
def gt_0(lst):
for elm in lst:
if elm > 0:
return True
return False
这些是性能测试的结果:
>> %timeit any(elm > 0 for elm in lst)
>> 10 loops, best of 3: 35.9 ms per loop
>> %timeit gt_0(lst)
>> 100 loops, best of 3: 16 ms per loop
我希望两者具有完全相同的性能,但是 any()
如果慢两倍。为什么?
最佳答案
原因是您已经通过了 generator expression到 any()
函数。 Python 需要将生成器表达式转换为生成器函数,这就是它执行速度较慢的原因。因为生成器函数每次都需要调用__next__()
方法来生成项目并将其传递给any
。这是在手动定义的函数中,您将整个列表传递给已经准备好所有项目的函数。
通过使用列表理解而不是生成器表达式,您可以更好地看到差异:
In [4]: %timeit any(elm > 0 for elm in lst)
10 loops, best of 3: 66.8 ms per loop
In [6]: test_list = [elm > 0 for elm in lst]
In [7]: %timeit any(test_list)
100 loops, best of 3: 4.93 ms per loop
代码中的另一个瓶颈比对 next
的额外调用成本更高,这是您进行比较的方式。如评论中所述,您的手动功能的更好等价物是:
any(True for elm in lst if elm > 0)
在这种情况下,您正在与生成器表达式进行比较,它的执行时间几乎与您手动定义的函数相同(我猜,最细微的差别是因为生成器。)为了更深入地了解根本原因阅读Ashwini的答案。
关于Python:任何()意外的表现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44802682/