【问题标题】:Why is `if` so much faster when checked before a statement than after a statement?为什么在语句之前检查“if”比在语句之后检查时快得多?
【发布时间】:2026-01-29 22:30:01
【问题描述】:

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

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))

不管x的初始值是5还是15,它都会输出大约6秒。


我知道x &lt; 10 会更慢,因为我们首先调用x -= 10 然后设置x = 0 而不是简单地设置x 一次。

问题是,99% 的情况下,我的程序中 x 的初始值设置为远高于 10 的数字,所以我认为我会使用较短的版本,因为大多数时候我应该看不出性能上的差异。

但是,即使x &gt; 10,性能也存在巨大差异,这是为什么呢?

【问题讨论】:

  • python 2.7 中也会出现这种时间差异。

标签: python performance python-3.x performance-testing


【解决方案1】:

你的前提是错误的。 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

【讨论】:

  • 我以前用过timeit.timeit() 百万次,我应该非常清楚设置参数的工作原理......有趣的是,如果我们的大脑考虑一切,那么它会错过如此明显的东西应该工作。谢谢你的回答,很好:)
  • @MarkusMeskanen 在评论 Will 的回答时,我实际上也被这个咬了,有人向我提到过(但那个人现在删除了他的评论,所以我不记得了,所以不能给予信任)。那句话让我得到了这个答案。
【解决方案2】:

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

这似乎至少有点可能是代码在timeit.timeit 下运行方式的产物。您可以通过计时单次运行代码来测试这一点:

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

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

【讨论】:

  • 我误解了setup参数,你的那部分答案至少是正确的。
  • @orlp xrange 是 python 2.X 的内置函数。 x = 5 是否在循环内并不重要,因为这两种方法都相同。使用此答案后行为仍然存在并不意味着这是一个错误的答案;这只是意味着差异不是使用timeit 的产物。
  • @dbliss 但这意味着答案很糟糕,因为这就是答案的全部内容,不是吗?顺便说一句,当前的反对票不是我的 - 我删除了我的,直到进一步检查。