简体   繁体   English

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

[英]Why is this method of testing for palindromes so much slower?

I have two different methods of testing for a palindrome. 我有两种不同的回文测试方法。 One is the following: 一个是以下内容:

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

Very simple, of course, but I had imagined it would be slow as it (surely) has to store the value of text[::-1] somewhere after reversing it, then it checks every character in both. 当然很简单,但我想象它会很慢,因为它(肯定)必须在反转后将某个text[::-1]的值保存在某处,然后检查两者中的每个字符。 So, I attempted another method: 所以,我尝试了另一种方法:

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

It starts at the start and end points, and works its way into the center. 它从起点和终点开始,然后进入中心。 This should, as far as I can tell, be faster, since it only checks [0, n // 2) and vice versa for the end. 据我所知,这应该更快,因为它只检查[0, n // 2) ,反之亦然。 However, when I use timeit to test these, the first is 0.32 and the second is 1.34 . 但是,当我使用timeit测试这些时,第一个是0.32 ,第二个是1.34 Why? 为什么?

I think it is informative to use dis to have a look at the the bytecode produced here: 我认为使用dis来查看这里生成的字节码是有益的:

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

Palindrome: 回文:

  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: 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

Essentially when doing the same amount of work C code will be faster than the corresponding python code. 基本上,当做相同数量的工作时,C代码将比相应的python代码更快。 As you can see the first approach calls a built in function, which is written in fast C. The second function has to do more of the work in python code, including handling the looping construct overhead, which will be slower than the call to the C. 正如您所看到的,第一种方法调用内置函数,它是用快速C编写的。第二种函数必须在python代码中完成更多工作,包括处理循环构造开销,这将比调用C。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM