我正在解决一些竞争性编码编码挑战。当我在列表中搜索时,我的解决方案超出了时间限制,但是当我用字符串搜索时,我的解决方案被接受了。
以下是示例代码:
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
**输出可能因系统而异,但趋势相同。
我发现字符串搜索速度非常快。我用谷歌搜索,但没有找到一个令人满意的推理。请帮我理解为什么字符串搜索最快?
答案 0 :(得分:6)
您的测试有偏见,您需要使用setup
参数忽略创建 list
或set
>>> 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
话虽如此,in
和str
的{{1}}操作是线性list
,O(N)
是常数set
(忽略了很多哈希冲突)。因此,对于更大的示例,O(1)
将是最快的,而set
和str
将非常相似。
答案 1 :(得分:4)
这与实际搜索速度和所有必须查找全局名称(list
或set
)并调用全局(包括帧保存和恢复)的内容几乎没有关系。
单独测试实际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数组并比较字节比比较动态数组中的对象要快,因为你不能事先知道所有对象都是同一类型。