为什么 if x in (1,2,3): 比 if x ==1 or x ==2 or x ==3 更快:
Why is if x in (1,2,3): faster than if x ==1 or x ==2 or x ==3:
根据 http://pylint.pycqa.org/en/latest/whatsnew/2.0.html in 选项比 multiple or 更快。
引用本站
A new check was added, consider-using-in.
This refactoring message is emitted when a variable is compared
against multiple values concatenated by ors instead of using the
faster, more idiomatic "in" check.
if variable == 1 or variable == 2 or variable == 3: # bad
pass
if variable in (1, 2, 3): # good
pass
首先,in选项是否更快?因为肯定它必须和多个 or 做同样的事情,难道每次创建元组的内存损失不值得吗?
一方面,constant-folding optimization 会预先计算常量元组,因此 in (1, 2, 3)
不会每次都构建整个元组。无需每次都构建元组,in
方法实际上比 ==
方法具有更少的字节码解释开销并且运行速度更快。
另一方面,这只适用于常量元组。当元组不是编译时常量时,in
通常较慢,例如 in (x, y, z)
。 Pylint 将报告 consider-using-in
,即使在 in
速度较慢的情况下也是如此。
我认为 Pylint 甚至会在 in
会改变代码含义的情况下报告 consider-using-in
,例如 x == 1 or x == thing_with_side_effects()
.
通常情况下,我认为 pylint 是错误的。情况并非总是如此。 只有 元组可以在字节码编译步骤中作为常量缓存,但情况并非总是如此。考虑简单的:
In [1]: def using_in(a, b, c):
...: 42 in (a,b,c)
...:
In [2]: def using_or(a, b, c):
...: 42 == a or 42 == b or 42 == c
...:
In [3]: %timeit using_in(1,2,3)
125 ns ± 3.82 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [4]: %timeit using_or(1,2,3)
119 ns ± 1.96 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
但更重要的是,这类决策几乎总是与代码清晰度或可维护性有关。无论如何,性能差异通常可以忽略不计。
老实说,如果您正在编写代码以在此级别进行优化,CPython 可能不适合您。
根据 http://pylint.pycqa.org/en/latest/whatsnew/2.0.html in 选项比 multiple or 更快。
引用本站
A new check was added, consider-using-in.
This refactoring message is emitted when a variable is compared against multiple values concatenated by ors instead of using the faster, more idiomatic "in" check.
if variable == 1 or variable == 2 or variable == 3: # bad pass
if variable in (1, 2, 3): # good pass
首先,in选项是否更快?因为肯定它必须和多个 or 做同样的事情,难道每次创建元组的内存损失不值得吗?
一方面,constant-folding optimization 会预先计算常量元组,因此 in (1, 2, 3)
不会每次都构建整个元组。无需每次都构建元组,in
方法实际上比 ==
方法具有更少的字节码解释开销并且运行速度更快。
另一方面,这只适用于常量元组。当元组不是编译时常量时,in
通常较慢,例如 in (x, y, z)
。 Pylint 将报告 consider-using-in
,即使在 in
速度较慢的情况下也是如此。
我认为 Pylint 甚至会在 in
会改变代码含义的情况下报告 consider-using-in
,例如 x == 1 or x == thing_with_side_effects()
.
通常情况下,我认为 pylint 是错误的。情况并非总是如此。 只有 元组可以在字节码编译步骤中作为常量缓存,但情况并非总是如此。考虑简单的:
In [1]: def using_in(a, b, c):
...: 42 in (a,b,c)
...:
In [2]: def using_or(a, b, c):
...: 42 == a or 42 == b or 42 == c
...:
In [3]: %timeit using_in(1,2,3)
125 ns ± 3.82 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [4]: %timeit using_or(1,2,3)
119 ns ± 1.96 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
但更重要的是,这类决策几乎总是与代码清晰度或可维护性有关。无论如何,性能差异通常可以忽略不计。
老实说,如果您正在编写代码以在此级别进行优化,CPython 可能不适合您。