开发者社区> 问答> 正文

Python:任何意外的性能

我正在比较any()内置函数的性能和文档建议的实际实现: 我在下面的列表中寻找一个大于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()方法要慢两倍。为什么? 问题来源StackOverflow 地址:/questions/59386919/why-is-any-slower-than-yield-for-checking-if-any-element-exists-matching-condi

展开
收起
kun坤 2019-12-25 21:46:35 343 0
1 条回答
写回答
取消 提交回答
  • 原因是您向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)
    

    在本例中,您正在与生成器表达式进行比较,它将几乎在与手动定义的函数相同的时间内执行(我猜,最细微的差异是由于生成器造成的)。要更深入地了解其背后的原因,请阅读阿什维尼的答案。

    2019-12-25 21:46:46
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
From Python Scikit-Learn to Sc 立即下载
Data Pre-Processing in Python: 立即下载
双剑合璧-Python和大数据计算平台的结合 立即下载