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

Blu*_*ken 9 python performance cpython python-3.x

我正在做一些关于列表上的操作速度的实验。为此,我定义了两个列表: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)
Run Code Online (Sandbox Code Playgroud)

的时间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
"""
Run Code Online (Sandbox Code Playgroud)

che*_*ner 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__