为什么在CPython中`len(l)!= 0'比`bool(l)`快?

时间:2019-08-08 12:50:26

标签: python python-3.x performance cpython

我正在做一些关于列表上的操作速度的实验。为此,我定义了两个列表:l_short = []l_long = list(range(10**7))

这个想法是将bool(l)len(l) != 0

进行比较

if竞赛中,以下实现要快if l: pass而不是if len(l) != 0: pass

但是在没有if竞赛的情况下,我得到了以下结果:

%%timeit
len(l_long) != 0
# 59.8 ns ± 0.358 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%%timeit
bool(l_long)
# 63.3 ns ± 0.192 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

bool的时间稍长,为什么呢?

以下是使用dis(FYI)的字节码

dis("len(l_long) != 0")
"""
  1           0 LOAD_NAME                0 (len)
              2 LOAD_NAME                1 (l_long)
              4 CALL_FUNCTION            1
              6 LOAD_CONST               0 (0)
              8 COMPARE_OP               3 (!=)
             10 RETURN_VALUE
"""

dis("bool(l_long)")
"""
  1           0 LOAD_NAME                0 (bool)
              2 LOAD_NAME                1 (l_long)
              4 CALL_FUNCTION            1
              6 RETURN_VALUE
"""

1 个答案:

答案 0 :(得分:7)

bool(l_long)首先尝试呼叫l_long.__bool_();但是,list.__bool__未定义。下一步是呼叫l_long.__len__() != 0

另一方面,

len(l_long) != 0直接进入l_long.__len__()

您看到的时差本质上是在仍然呼叫AttributeError之前赶上l_long.__bool__引起的l_long.__len__所花费的时间。