为什么在语句之前检查 if 比在语句之后检查要快得多?

Why is `if` so much faster when checked before a statement than after a statement?

这是我的意思的一个例子:

s = """
if x > 10:
    x -= 10
else:
    x = 0
"""
import timeit
print(timeit.timeit(s, setup="x=5", number=99999999))

无论设置如何,在我的计算机上输出大约 3 秒(x=5x=15,没有区别)


如果我使用更短的代码,首先减少 x -= 10 然后才检查是否 x < 0,我会得到更糟糕的结果:

s = """
x -= 10
if x < 0:
    x = 0
"""
import timeit
print(timeit.timeit(s, setup="x=5", number=99999999))

它输出大约 6 秒,同样不管 x 的初始值是 5 还是 15


我知道当 x < 10 时会比较慢,因为我们先调用 x -= 10 然后设置 x = 0 而不是简单地设置一次 x

事实是,99% 的情况下 x 在我的程序中的初始值设置为比 10 高得多的数字,所以我想我会使用较短的版本,因为大多数我应该看不到性能差异的时间。

然而,即使在 x > 10 时,性能也存在巨大差异,这是为什么?

更新:这是错误的;留下它作为记录没有导致行为

的原因

这似乎至少有点可能是代码在 timeit.timeit 下 运行 的产物。您可以通过计时单个 运行 代码来对此进行测试,例如:

x = 5
for i in xrange(99999999):
  x -= 10
  if x < 0:
    x = 0

对于第二种情况,并将该时间与第一种情况的类似重写进行比较。

你的前提是错误的。 setup整个timeit只得到一次运行。如果您确保 x 保持在 10 以上,那么症状就会消失:

>>> s1 = """
... if x > 10:
...     x -= 10
... else:
...     x = 0
... """
>>> s2 = """
... x -= 10
... if x < 0:
...     x = 0
... """
>>> import timeit
>>> print(timeit.timeit(s1, setup="x=1000000000", number=99999999))
8.934118068675566
>>> print(timeit.timeit(s2, setup="x=1000000000", number=99999999))
8.744505329313448