Python 为什么“|”和“或”之间的性能会因不同的值而不同?

Python 为什么“|”和“或”之间的性能会因不同的值而不同?,python,performance,logical-operators,boolean-logic,Python,Performance,Logical Operators,Boolean Logic,我为运营商计时,我发现: >>> timeit.timeit("10000000<2 or 10000000>1000",number=10000000) 0.4213107880004827 >>> timeit.timeit("(10000000<2) | (10000000>1000)",number=10000000) 0.5472174039969104 >>> timeit.timeit("1000<

我为运营商计时,我发现:

>>> timeit.timeit("10000000<2 or 10000000>1000",number=10000000)
0.4213107880004827
>>> timeit.timeit("(10000000<2) | (10000000>1000)",number=10000000)
0.5472174039969104

>>> timeit.timeit("1000<200000 or 100>1000",number=10000000)
0.26014828799998213
>>> timeit.timeit("(1000<200000) | (100>1000)",number=10000000)
0.49938497000039206

发生了什么事?这是预期的吗?我相信
|
总是检查两个操作数,即使第一个操作数的计算结果为
True
。因此,至少在第一个操作数为
True
的情况下,
不应该一直更快吗?

或和|不是完全相同的运算符

执行逻辑快捷方式或
|
执行按位或

result = expression1 or expression2 
与相同

if bool(expression1):
    result = expression1
else:
    result = expression2
因此,如果表达式1为真,则表达式2甚至不会被计算

鉴于:

结果=表达式1 |表达式2

对两个值执行按位或。所以表达式1和表达式2必须产生整数。(True被解释为整数1)

查看下面的输出示例

In [8]: "{0:b}".format(0b100 | 0b001)                                           
Out[8]: '101'

In [9]: "{0:b}".format(0b100 or 0b001)                                          
Out[9]: '100'
澄清: 如果
|
/“或”右侧的运算符计算速度快,则 它可能会使用更快的“|”,因为它会创建无分支代码

另一方面,如果右侧的运算符是CPU密集型的,而左侧的运算符有时为true,有时为false,则
会更快

在您的示例中,右侧是一个简单的整数,因此
|
可能会快一点。(与我最初的回答相反)

几乎没有执行时间差的微小操作必须反复计时。让我们假设在一天中的不同时间对它们计时几百次。两者都有

timeit的问题在于,您在一个操作系统上执行python,该操作系统运行多个进程,并且没有100%可预测的环境


所以我会非常小心地解释运行时中的微小差异。

|
是按位或,
是逻辑或。他们是两个不同的操作员。是的,我明白。但为什么在某些情况下,
按位
更快,而在另一些情况下,
逻辑
?它所比较的都是
Truthy
Falsy
,因为它不比较Truthy和Falsy。它执行位运算。好的,
|
(有效为1和0)之间执行位运算,
之间执行逻辑运算。那么,他们的表现不应该在所有情况下都保持一致吗?例如,对于整数包容检查,范围(1,5)中的
1
将始终比
0
慢,或者
将在第一个真实零件上停止,因此不必评估任何后续零件<代码>
需要这两个部分,并对其执行计算,然后仍然评估该计算的结果。“所以我同意你的假设,通常
应该比
快”—这在逻辑上是不正确的。事实上,在不知道这些操作如何在内部实现的情况下,在现代机器上哪些操作更快并不明显。根据您给定的描述,
|
应该比
快很多,因为它是无分支的。当然,在实际的实现中这是不同的。这取决于右侧的简单表达式位于
/
右侧的表达式应该更快(没有分支)。对于CPU密集型的右had运算符,
应该更快“它取决于右侧的表达式”-是的,但该表达式是对单个整数的简单逻辑运算。谢谢Konrad。我修改了我的答案
In [8]: "{0:b}".format(0b100 | 0b001)                                           
Out[8]: '101'

In [9]: "{0:b}".format(0b100 or 0b001)                                          
Out[9]: '100'