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

问题描述 投票:0回答:2

我写了一个代码来找到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 
python-3.x if-statement python-3.5
2个回答
1
投票

您的代码的两个版本不会以相同的方式计算结果,因此它们花费不同的时间不应该太大。

当你使用if / elif / else时,你经常会多次计算相同的next值。例如,六个可以计算为2*33*2。因为当i2i3i56的最小值时,只有n2n3n5值中的一个会增加,所以你最终会在第一次传球时选择i2增加,然后在第二次传球时选择i3,因为n3还是六点。 if next != ugly[count-1]:检查将阻止重复值在输出中结束,但您仍需要额外运行循环体。

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


1
投票

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

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

这是很多测试。特别要求min获得3个值是过度的。

我已经重写了没有min的循环(如果值相等,min返回最左边的参数,作为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,因为它是一个内置函数

© www.soinside.com 2019 - 2024. All rights reserved.