Python:任何()意外的表现

标签 python python-2.7 performance python-3.x any

我正在将 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 expressionany() 函数。 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/

相关文章:

python-3.x - 断言包装函数

python - 为什么在使用替换函数时反向引用在 Python 的 re.sub 中不起作用?

mysql - 在 MySQL 中进行模式匹配的有效方法是什么?

python - python中区分乱码/错误和外来词/名称的算法或工具?

python - 替换字符串中某个字符的实例

python-2.7 - 如何使 opencv2 中无法识别的面孔被标记为 "unknown"?

algorithm - 为什么 MergeSort 的奇偶拆分为 'faster'?

python - python中的内存错误

python - 多幅图像和一幅基本图像之间的欧氏距离

java - Array 和 ArrayList 位置访问性能