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

时间:2017-12-21 19:40:04

标签: python-3.x if-statement python-3.5

我写了一个代码来查找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 

2 个答案:

答案 0 :(得分:1)

您的代码的两个版本不会以相同的方式计算结果,因此它们花费不同的时间并不会太令人意外。

当您使用if / elif / else时,您通常会多次计算相同的next值。例如,六个可以计算为2*33*2。由于当i2i3i5,{{{{}}的最小值时,6n2n3值中只有一个会增加1}},您最终会在第一次传递时选择n5增加,然后在第二次传递时选择i2,因为i3仍为6。 n3检查将阻止重复值在输出中结束,但您仍需要额外运行循环体。

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

答案 1 :(得分:1)

不确定是否可以解释,但在我看来,你想要最快的方法和你的代码

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

这是一个很多的测试。特别为3个值调用min是过度的。

我在没有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,因为它是内置函数