Python字符串搜索效率

时间:2011-08-05 22:23:30

标签: python performance

对于非常大的字符串(跨越多行),使用Python的内置字符串搜索或拆分大字符串(可能在\n上)并迭代搜索较小的字符串会更快吗?

,例如,非常大的字符串:

for l in get_mother_of_all_strings().split('\n'):
 if 'target' in l:
   return True
return False

return 'target' in get_mother_of_all_strings()

6 个答案:

答案 0 :(得分:13)

可能当然是第二个,我认为在大字符串中搜索或在小字符串中搜索时没有任何区别。由于线条较短,您可以跳过一些字符,但拆分操作也有成本(搜索\n,创建不同的字符串,创建列表),循环在python中完成。

字符串__contain__方法在C中实现,因此明显更快。

还要考虑第二个方法在找到第一个匹配后立即中止,但第一个方法在开始在其中搜索之前将所有字符串拆分

通过简单的基准测试可以快速证明这一点:

import timeit

prepare = """
with open('bible.txt') as fh:
    text = fh.read()
"""

presplit_prepare = """
with open('bible.txt') as fh:
    text = fh.read()
lines = text.split('\\n')
"""

longsearch = """
'hello' in text
"""

splitsearch = """
for line in text.split('\\n'):
    if 'hello' in line:
        break
"""

presplitsearch = """
for line in lines:
    if 'hello' in line:
        break
"""


benchmark = timeit.Timer(longsearch, prepare)
print "IN on big string takes:", benchmark.timeit(1000), "seconds"

benchmark = timeit.Timer(splitsearch, prepare)
print "IN on splitted string takes:", benchmark.timeit(1000), "seconds"

benchmark = timeit.Timer(presplitsearch, presplit_prepare)
print "IN on pre-splitted string takes:", benchmark.timeit(1000), "seconds"

结果是:

IN on big string takes: 4.27126097679 seconds
IN on splitted string takes: 35.9622690678 seconds
IN on pre-splitted string takes: 11.815297842 seconds

bible.txt文件实际圣经,我在这里找到了它:http://patriot.net/~bmcgin/kjvpage.html(文本版)

答案 1 :(得分:1)

如果您只匹配一次以查看子字符串是否完全在字符串中,则两种方法大致相同,并且您将更多的开销分成单独的逐行搜索;所以大字符串搜索速度要快一些。

如果你必须做多个匹配,那么我会将字符串标记化并将它们填入字典或设置并存储在内存中。

s = 'SOME REALLY LONG STRING'
tokens = set(s.split())
return substring in tokens

答案 2 :(得分:1)

第二个更快,这里有一些测量数据:

def get_mother_of_all_strings():
    return "abcdefg\nhijklmnopqr\nstuvwxyz\naatargetbb"

first: 2.00
second: 0.26

答案 3 :(得分:0)

python中的for循环很慢,而且拆分一个大字符串也很慢。所以搜索大字符串要快得多。

答案 4 :(得分:0)

第二种方式更快,分切又增加了一次O(n)迭代的搜索和分隔,每个子列表的共存内存,然后接近 O(n ^ 2) 来查看每个子列表并在其中搜索字符串。只需 O(n)即可搜索更大的字符串。

答案 5 :(得分:0)

import timeit

a = #a really long string with multiple lines and target near the end

timeit.timeit(stmt='["target" in x for x in a.split("\\n")]', setup='a = """%s"""'%a)
23.499058284211792
timeit.timeit(stmt='"target" in a', setup='a = """%s"""'%a)
5.2557157624293325

因此,搜索大字符串的速度要快于较小字符串的拆分列表。