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'