为什么这种测试回文的方法要慢得多?

时间:2015-11-30 18:15:31

标签: python native-code python-performance

我有两种不同的回文测试方法。一个是以下内容:

def palindrome(text):
    return text == text[::-1]

当然很简单,但是我想象它会很慢,因为它(当然)必须在反转它之后在某处保存text[::-1]的值,然后检查两者中的每个字符。所以,我尝试了另一种方法:

def palindrome_2(text):
    left = 0
    right = len(text) - 1
    while left < right:
        if text[left] != text[right]:
            return False
        right -= 1
        left += 1
    return True

从起点和终点开始,然后进入中心。据我所知,这应该更快,因为它只检查[0, n // 2),反之亦然。但是,当我使用timeit测试这些时,第一个是0.32,第二个是1.34。为什么呢?

1 个答案:

答案 0 :(得分:5)

我认为使用dis来查看此处生成的字节码是有益的:

import dis
dis.dis(palindrome)
dis.dis(palindrome_2)

回文:

  4           0 LOAD_FAST                0 (text)
              3 LOAD_FAST                0 (text)
              6 LOAD_CONST               0 (None)
              9 LOAD_CONST               0 (None)
             12 LOAD_CONST               2 (-1)
             15 BUILD_SLICE              3
             18 BINARY_SUBSCR
             19 COMPARE_OP               2 (==)
             22 RETURN_VALUE

Palindrome_2:

 10           0 LOAD_CONST               1 (0)
              3 STORE_FAST               1 (left)

 11           6 LOAD_GLOBAL              0 (len)
              9 LOAD_FAST                0 (text)
             12 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             15 LOAD_CONST               2 (1)
             18 BINARY_SUBTRACT
             19 STORE_FAST               2 (right)

 12          22 SETUP_LOOP              60 (to 85)
        >>   25 LOAD_FAST                1 (left)
             28 LOAD_FAST                2 (right)
             31 COMPARE_OP               0 (<)
             34 POP_JUMP_IF_FALSE       84

 13          37 LOAD_FAST                0 (text)
             40 LOAD_FAST                1 (left)
             43 BINARY_SUBSCR
             44 LOAD_FAST                0 (text)
             47 LOAD_FAST                2 (right)
             50 BINARY_SUBSCR
             51 COMPARE_OP               3 (!=)
             54 POP_JUMP_IF_FALSE       61

 14          57 LOAD_CONST               3 (False)
             60 RETURN_VALUE

 15     >>   61 LOAD_FAST                2 (right)
             64 LOAD_CONST               2 (1)
             67 INPLACE_SUBTRACT
             68 STORE_FAST               2 (right)

 16          71 LOAD_FAST                1 (left)
             74 LOAD_CONST               2 (1)
             77 INPLACE_ADD
             78 STORE_FAST               1 (left)
             81 JUMP_ABSOLUTE           25
        >>   84 POP_BLOCK

 17     >>   85 LOAD_CONST               4 (True)
             88 RETURN_VALUE

基本上,当执行相同数量的工作时,C代码将比相应的python代码更快。 正如您所看到的,第一种方法调用内置函数,它是用快速C编写的。第二种函数必须在python代码中完成更多工作,包括处理循环构造开销,这将比调用下进行。