与列表搜索和设置搜索相比,为什么字符串搜索速度最快?

时间:2015-08-17 11:34:26

标签: python string python-2.7

我正在解决一些竞争性编码编码挑战。当我在列表中搜索时,我的解决方案超出了时间限制,但是当我用字符串搜索时,我的解决方案被接受了。

以下是示例代码:

CODE

line.rtrim('\n')

输出

import timeit

list = timeit.Timer("'A' in list('AEIOU')")
set = timeit.Timer("'A' in set('AEIOU')")
string = timeit.Timer("'A' in 'AEIOU'")

print 'List search :',list.timeit(999999)
print 'Set search',set.timeit(999999)
print 'String search',string.timeit(999999)

*此输出是在ideone.com中获得的...... http://ideone.com/5FxkX2
**输出可能因系统而异,但趋势相同。

我发现字符串搜索速度非常快。我用谷歌搜索,但没有找到一个令人满意的推理。请帮我理解为什么字符串搜索最快?

2 个答案:

答案 0 :(得分:6)

您的测试有偏见,您需要使用setup参数忽略创建 listset

的时间
>>> timeit.timeit("'A' in l", "l = list('AEIOU')")
0.06389708405846951
>>> timeit.timeit("'A' in s", "s = set('AEIOU')")
0.05960524183085081
>>> timeit.timeit("'A' in s", "s = 'AEIOU'")
0.05756433387793081

话虽如此,instr的{​​{1}}操作是线性listO(N)是常数set(忽略了很多哈希冲突)。因此,对于更大的示例,O(1)将是最快的,而setstr将非常相似。

答案 1 :(得分:4)

这与实际搜索速度和所有必须查找全局名称(listset)并调用全局(包括帧保存和恢复)的内容几乎没有关系。

单独测试实际list运算符 ,而不是通过调用:

in

现在时间太接近了,因为你的对象太小了。使用更大的输入来实际看到差异。

仅仅使用更多字符会增加对比度:

>>> import timeit
>>> timeit.Timer("'A' in l", "l = list('AEIOU')").timeit(999999)
0.0490870475769043
>>> timeit.Timer("'A' in s", "s = set('AEIOU')").timeit(999999)
0.0507349967956543
>>> timeit.Timer("'A' in s", "s = 'AEIOU'").timeit(999999)
0.04982495307922363

现在>>> timeit.Timer("'A' in l", "from string import ascii_letters, digits, whitespace; l = list(ascii_letters + digits + whitespace)").timeit(999999) 0.38520193099975586 >>> timeit.Timer("'A' in s", "from string import ascii_letters, digits, whitespace; s = set(ascii_letters + digits + whitespace)").timeit(999999) 0.046868085861206055 >>> timeit.Timer("'A' in s", "from string import ascii_letters, digits, whitespace; s = ascii_letters + digits + whitespace").timeit(999999) 0.06492304801940918 对象开始获胜,列表对象显示速度较慢。

您还应该测试否定案例,其中角色在对象中:

set()

这里>>> timeit.Timer("'\xff' in l", "from string import ascii_letters, digits, whitespace; l = list(ascii_letters + digits + whitespace)").timeit(999999) 0.909243106842041 >>> timeit.Timer("'\xff' in s", "from string import ascii_letters, digits, whitespace; s = set(ascii_letters + digits + whitespace)").timeit(999999) 0.05034899711608887 >>> timeit.Timer("'\xff' in s", "from string import ascii_letters, digits, whitespace; s = ascii_letters + digits + whitespace").timeit(999999) 0.09932804107666016 对象确实很出色。

请注意,在两种情况下,字符串搜索仍然会击败列表搜索;这是因为迭代C数组并比较字节比比较动态数组中的对象要快,因为你不能事先知道所有对象都是同一类型。