sum()是否占用python3中循环的执行时间

时间:2018-07-25 16:17:23

标签: python-3.x execution-time

我在循环中使用了sum(),执行过程花费了4秒钟以上的时间,sum()是否等于嵌套循环?

def arrayMaxConsecutiveSum(inputArray, k):
    cop=k
    lis=[]
    i=0
    while i < len(inputArray):
        inpu=sum(inputArray[i:cop])
        lis.append(inpu)
        cop+=1
        i+=1
    return max(lis)

2 个答案:

答案 0 :(得分:4)

sum被实现为C ++库,因此尽管您仍然以任何一种方式运行嵌套循环,它仍将比Python for循环更快。为了说明这一点,我在这里为您的代码计时,以及使用Python循环代替的修改代码:

def arrayMaxConsecutiveSumLoop(inputArray, k):
    cop=k
    lis=[]
    i=0
    while i < len(inputArray) - k:
        inpu = 0
        for j in range(i, cop):  # for-loop in place of sum
            inpu += inputArray[j]
        lis.append(inpu)
        cop += 1
        i += 1
    return max(lis)

时间是:

arrayMaxConsecutiveSum(np.random.rand(10000), 100)
111 ms ± 1.42 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

arrayMaxConsecutiveSumLoop(np.random.rand(10000), 100)
198 ms ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

因此,sum(您的版本)的实施速度要快两倍左右!

更好的实现方式

我使用numpy重新编写了您的函数,以使其更快地运行!此实现没有嵌套循环,并且是O(n),并且可以通过非常快的numpy库实现。

import numpy as np
def array_max_consecutive_sum(input_array, k):
    result = np.cumsum(input_array)
    return max(result[k:] - result[:-k])

array_max_consecutive_sum(np.random.rand(10000), 100)
688 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

那快150倍!

其他选项

顺便说一下,接受的答案(在撰写本文时)给出了时间安排:

6.46 ms ± 147 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

速度快,但仍仅是上述numpy实现速度的十分之一。而且,结果是错误的。

答案 1 :(得分:1)

是的,为了将所有元素加在一起,sum代码必须遍历inputArray(从i到cop)。

此外,len(inputArray)还必须遍历整个数组以获取其长度。因此,您的解决方案是O(n * k)

您可以使用以下方法将代码优化为O(n)解决方案:

def arrayMaxConsecutiveSum(inputArray, k):
    max = sum(inputArray[0:k])
    bucket = max
    count = len(inputArray)
    for i in range(1, 1 + count - k):
        prev = inputArray[i - 1]
        cur = inputArray[i + k - 1]
        bucket += cur - prev
        if bucket > max:
            max = bucket
    return max

此算法仅在数组上循环一次。想象一下,有一个固定的铲斗沿一条线滑下。随着i的增加,存储桶需要带走最近的物品,但是最旧的物品会掉下来。使用此逻辑,您只需要将每个项目最多查看两次-将其添加到存储桶中时,以及将其从另一端移出时。

**请注意,为清楚起见,省略了特殊情况的处理**