为什么 `len(l) != 0` 比 CPython 中的 `bool(l)` 快?
Why is `len(l) != 0` faster than `bool(l)` in CPython?
我正在做一些关于列表操作速度的实验。为此,我定义了两个列表:l_short = []
和 l_long = list(range(10**7))
.
想法是将 bool(l)
与 len(l) != 0
进行比较
在 if
比赛中,以下实施比 if len(l) != 0: pass
快很多 if l: 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
的字节码(仅供参考)
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
"""
bool(l_long)
首先尝试调用 l_long.__bool_()
;但是,list.__bool__
未定义。下一步是调用 l_long.__len__() != 0
.
len(l_long) != 0
,另一方面,直接进入 l_long.__len__()
您看到的时差本质上是在调用 l_long.__len__
之前捕获 l_long.__bool__
引发的 AttributeError
所花费的时间。
我正在做一些关于列表操作速度的实验。为此,我定义了两个列表:l_short = []
和 l_long = list(range(10**7))
.
想法是将 bool(l)
与 len(l) != 0
在 if
比赛中,以下实施比 if len(l) != 0: pass
if l: 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
的字节码(仅供参考)
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
"""
bool(l_long)
首先尝试调用 l_long.__bool_()
;但是,list.__bool__
未定义。下一步是调用 l_long.__len__() != 0
.
len(l_long) != 0
,另一方面,直接进入 l_long.__len__()
您看到的时差本质上是在调用 l_long.__len__
之前捕获 l_long.__bool__
引发的 AttributeError
所花费的时间。