使用三个 IF 与使用 IF-ELIF-ELSE:前者更快

Using three IFs vs using IF-ELIF-ELSE: former is faster

我写了一个代码来找到ugly numbers。在尝试使其更快时,我发现使用 3 个 IF 而不是 IF-ELIF-ELSE 可以使我的代码更快。我尝试了 运行 多次迭代 n 的代码,发现大部分时间都是如此。

我觉得 IF-ELIF-ELSE 应该更快,因为如果满足其中一个条件,它就不会进入其他条件。但我无法找到实际发生的任何逻辑。

代码如下:

ugly = [0]*n
ugly[0] = 1
i2, i3, i5 = 0, 0, 0

count = 1

while count<n:
    n2 = ugly[i2]*2
    n3 = ugly[i3]*3
    n5 = ugly[i5]*5

    next = min(n2, n3, n5)

    if next==n2:
        i2 += 1
    elif next==n3:
        i3 += 1
    else:
        i5 += 1

    if next != ugly[count-1]:
        ugly[count] = next
        count += 1 

您的代码的两个版本计算结果的方式不同,因此它们花费不同的时间不足为奇。

当您使用 if/elif/else 时,您通常会多次计算相同的 next 值。例如,六可以计算为 2*33*2。由于当 6n2n3n5,你最终会选择 i2 在第一遍递增,然后在第二遍选择 i3,因为 n3 仍然是六。 if next != ugly[count-1]: 检查将防止重复值出现在输出中,但您仍然需要额外 运行 循环体。

当您使用多个if时,所有生成最小n值的i值将同时递增。这意味着您将只计算每个难看的数字一次,即使它可以通过多种不同的方式生成。避免额外的工作意味着代码 运行s 更快。您也可以删除 if next != ugly[count-1]: 保护代码,因为您永远不会重复生成相同的值。

不确定是否能够解释,但在我看来您想要最快的方法和您的代码

  • 正在调用 min 执行函数调用 + 循环 + 比较
  • 然后它将最小值与 3 个值中的 2 个进行比较

那是 很多 的测试。专门为 3 个值调用 min 是多余的。

我重写了没有 min 的循环(如果值相等,min returns 最左边的参数,作为 Python 2 的实现细节,现在保证 python 3) 仅使用不等式测试(链接运算符)

while count<n:
    n2 = ugly[i2]*2
    n3 = ugly[i3]*3
    n5 = ugly[i5]*5

    if n5 >= n2 <= n3:
        next = n2
        i2+=1
    elif n5 >= n3 <= n2:
        next = n3
        i3 += 1
    else:
        next = n5
        i5 += 1

    # below: not changed
    if next != ugly[count-1]:
        ugly[count] = next
        count += 1

因为只有 3 个数字可以比较,所以这样的测试速度更快。

对于 n=2000000 在我的机器上:

  • 你的方法:7.78 秒
  • 我的方法:6.32秒

这两种代码当然会产生相同的结果。

请注意,我不会调用我的变量 next,因为它是一个内置函数