为什么这两个代码的执行时间如此不同?

时间:2020-01-24 21:34:28

标签: python python-3.x algorithm performance

我不明白这两个代码有什么不同,因为它们执行或多或少的相同操作,但是我增加的越多,两个代码之间的时间差就越大。这两个代码的Big O相同,因为第一个代码中的while循环与第二个代码中的for循环具有相同的目的,第一个代码中的嵌套for循环与第二个嵌套的while循环扫描所有元素一样。如果是这样,怎么可能? (这两个代码是外观序列的实现:https://en.wikipedia.org/wiki/Look-and-say_sequence

import time

a = time.time()

def look_and_say_sequence(first_element, n):

    while n != 1 :

        next_element , start , k = '' , first_element[0] , 0

        for x in first_element :
            if x != start :
                next_element , start , k = next_element + str(k) + start , x , 1
            else :
                k = k + 1

        first_element = next_element + str(k) + start
        n  = n - 1

    return first_element

look_and_say_sequence('1', 48)

b = time.time()

print(b-a)  # 10 SECONDS



#########################################################################################`

a = time.time()

def look_and_say_sequence(first, n):    
    result = first

    for _ in range(n-1):

        sequence = result
        result = ''
        index = 0

        while index < len(sequence):

            pending = sequence[index]
            count = 0

            while index < len(sequence) and pending == sequence[index]:
                count += 1
                index += 1

            result += "{}{}".format(count, pending)

    return result

look_and_say_sequence('1', 48)


b = time.time()

print(b-a) # 2 SECONDS

谢谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您的速度变慢了

next_element , start , k = next_element + str(k) + start , x , 1

,当next_element是一个非常长的字符串时,这会导致大量的运行时损失(随着n的增大,这种情况肯定会发生-next_element的长度超过500k个字符,n = 48)。尝试运行以下两个脚本:

import time

a = time.time()
s = ''
for i in range(99999):
  s = (s + '1') + '1' # comment this out
  # s += '1' + '1'  # and uncomment this to see the speed difference

b = time.time()
print(b-a)

您会发现使用+ =可以更快地运行。 Python从左到右求值,这意味着(s + '1')必须在附加+ '1'之前求出新字符串。这就是增加这么多减速的原因。

如果将问题行更改为

,则继续
next_element += str(k) + start
start = x
k = 1

您实际上会看到顶级算法运行得更快