2016-09-18 30 views
0

尝试评估in语句的性能:setlist。我知道我可以用模块time来做,但我想尝试timeit模块。 所以我的代码是未来:通过timeit模块对列表进行评估的奇怪结果

from timeit import Timer 


def func_to_test(val, s): 
    return val in s 

if __name__ == "__main__": 
    val = 346 
    n = 100000 
    s = set([x for x in range(n)]) 
    l = [x for x in range(n)] 
    list_timer = Timer("func_to_test(%s, %s)" % (val, l), "from __main__ import func_to_test") 
    set_timer = Timer("func_to_test(%s, %s)" % (val, s), "from __main__ import func_to_test") 
    print(list_timer.timeit(100)) 
    print(set_timer.timeit(100)) 

输出是:

0.1953735960000813 
0.6675883569996586 

但为什么in语句list “有” 比set更好的性能? 我知道这不是,但为什么有timeit模块的这些结果?

+0

尝试使用更大的N,在这种情况下,设定恒定因素可能只是有点高,所以不会比l对于增长较慢小号n – Natecat

回答

2

您的设置语句导入func_to_test,但它不会执行任何操作。因此,实际的时间测试不仅要计算成员资格测试所需的时间,还要计算创建列表(用于列表测试)或列表一组(用于设置测试)所需的时间。在建立语句创建迭代,这个问题消失:

>>> import timeit 
>>> timeit.timeit('346 in s', setup='s=list(range(100000))') 
9.412489017458922 
>>> timeit.timeit('346 in s', setup='s=set(list(range(100000)))') 
0.08872845571155352 
>>> timeit.timeit('346 in s', setup='s=set(range(100000))') 
0.09335872296618675 
+0

谢谢,你指出正确的时间。但为什么我的代码产生这样的结果? – Litwisha

+0

@Litwisha - 因为您的代码正在查看创建列表和测试成员资格需要多长时间,或者创建列表,创建一个集合并测试成员资格,而不仅仅是测试成员资格需要多长时间。 – TigerhawkT3

+0

这对我来说有点陌生。因为列表和集创建正在主块中进行评估,而不是在'func_to_test'中。 – Litwisha