Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 比较startswith()的速度与。在()_Python_Performance_Python 3.x_Time - Fatal编程技术网

Python 比较startswith()的速度与。在()

Python 比较startswith()的速度与。在(),python,performance,python-3.x,time,Python,Performance,Python 3.x,Time,我的印象是startswith必须比中的更快,原因很简单,中的必须进行更多的检查(允许正在查找的单词位于字符串中的任何位置)。但是我有我的怀疑,所以我决定timeit。下面给出了计时代码,您可能会注意到,我没有做太多计时工作;代码相当简单 import timeit setup1=''' def in_test(sent, word): if word in sent: return True else: return False ''' se

我的印象是
startswith
必须比
中的
更快,原因很简单,
中的
必须进行更多的检查(允许正在查找的单词位于字符串中的任何位置)。但是我有我的怀疑,所以我决定
timeit
。下面给出了计时代码,您可能会注意到,我没有做太多计时工作;代码相当简单

import timeit

setup1='''
def in_test(sent, word):
    if word in sent:
        return True
    else:
        return False
'''

setup2='''
def startswith_test(sent, word):
    if sent.startswith(word):
        return True
    else:
        return False
'''

print(timeit.timeit('in_test("this is a standard sentence", "this")', setup=setup1))
print(timeit.timeit('startswith_test("this is a standard sentence", "this")', setup=setup2))
结果:

>> in:         0.11912814951705597
>> startswith: 0.22812353561129417
因此,
startswith
的速度是原来的两倍!。。鉴于我在上面所说的,我觉得这种行为非常令人费解。我对这两个的计时是否有问题,或者
中的
确实更快了?若然,原因为何

请注意,即使它们都返回
False
,结果也非常相似(在这种情况下,
中的
必须实际遍历整个句子,以防它之前短路):


如果I必须从头开始实现这两个函数,它看起来会像这样(伪代码):

startswith
:开始逐个比较单词字母和句子字母,直到a)单词耗尽(返回True)或b)检查返回False(返回False)

中:对于在句子中可以找到单词首字母的每个位置,调用
开始

我就是不明白



只是想说明一下,
中的
的startswith
不相等的;我只是在说一个例子,一个人试图查找的单词必须是字符串中的第一个

这是因为你必须查找并调用一个方法<
中的code>是专门化的,并直接导致
比较操作(调用它,依次调用
PySequence\u Contains
),而
str.startswith
则通过较慢的字节码:

2 LOAD_ATTR                0 (startswith)
4 LOAD_FAST                1 (word)
6 CALL_FUNCTION            1              # the slow part
中的
替换为
中的
。\uuuuu包含
,强制对该情况进行函数调用,这几乎抵消了速度差:

setup1='''
def in_test(sent, word):
    if sent.__contains__(word):
        return True
    else:
        return False
'''
以及时间安排:

print(timeit.timeit('in_test("this is a standard sentence", "this")', setup=setup1))
print(timeit.timeit('startswith_test("this is a standard sentence", "this")', setup=setup2))
0.43849368393421173
0.4993997460696846

中的
之所以在这里获胜,是因为它不需要经过整个函数调用设置,而且它提供了有利的案例

您正在比较字符串上的运算符与属性查找和函数调用。第二个会有更高的开销,即使第一个会占用大量数据的很长时间

此外,您正在查找第一个单词,因此如果它确实匹配,
中的
将查看与
startswith()相同的数据。要查看差异,您应该查看悲观情况(未找到结果,或字符串末尾匹配):


如果查看函数生成的字节码:

>>> dis.dis(in_test)
  2           0 LOAD_FAST                1 (word)
              3 LOAD_FAST                0 (sent)
              6 COMPARE_OP               6 (in)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_CONST               1 (True)
             15 RETURN_VALUE

  5     >>   16 LOAD_CONST               2 (False)
             19 RETURN_VALUE
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE
您会注意到有很多开销与字符串匹配没有直接关系。在更简单的函数上执行测试:

def in_test(sent, word):
    return word in sent

将更加可靠。

谢谢您的回答。悲观案例已经在编辑的帖子上了。你的悲观案例很短。看4个字符-vs-40只是一个舍入错误。看看4-vs-4000,你就会发现其中的区别。我理解,但我想用其中的任何一个来检查像这样的小句子,而不是整个文本。但是现在它确实更有意义了。所以我们可以说,
in
是O(n),而
startswith
是O(c),但是对于小的
n
So(n)更好,对吗?确切地说:)就是这样,有利的情况似乎没有这么大的影响;悲观的情况产生了同样的结果。更像字符串的长度和
startswith
的开销,我应该更详细@Ev.Kounis:-)长度就是我所说的有利情况。事实上,在一个小字符串中是否存在匹配不会产生太大的差异。现在我们回到同一页xD
>>> dis.dis(in_test)
  2           0 LOAD_FAST                1 (word)
              3 LOAD_FAST                0 (sent)
              6 COMPARE_OP               6 (in)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_CONST               1 (True)
             15 RETURN_VALUE

  5     >>   16 LOAD_CONST               2 (False)
             19 RETURN_VALUE
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE
def in_test(sent, word):
    return word in sent