我尝试在set
,list
和tuple
之间测试速度,并得到了令人惊讶的结果。
在此之前,基于此答案,我知道set
比list
更快。
这是我的测试代码:
import timeit,time
from sys import getsizeof as Size
List_Test = [range(1000)]
print("The Size of List is : {}".format(Size(List_Test)))
Set_Test = set(range(1000))
print("The Size of Set is : {}".format(Size(Set_Test)))
Tuple_Test = tuple(range(1000))
print("The Size of Tuple is : {}".format(Size(Tuple_Test)))
print("\nNow is to test speed\n")
time.sleep(3)
def Create_List():
List = [i for i in range(1000)]
def Test_List():
for i in List_Test:
if i == 6:
break
def Create_Set():
Set = set(i for i in range(1000))
def Test_Set():
for i in Set_Test:
if i == 6:
break
def Create_Tuple():
Tuple = tuple(i for i in range(1000))
def Test_Tuple():
for i in Tuple_Test:
if i == 6:
break
t = timeit.repeat(stmt="Create_List()",number=1000,setup="from __main__ import Create_List", repeat=30)
print("The Time of Create_List : {}".format(sum(t)/len(t)))
t = timeit.repeat(stmt="Create_Tuple()",number=1000,setup="from __main__ import Create_Tuple", repeat=30)
print("The Time of Create_Tuple : {}".format(sum(t)/len(t)))
t = timeit.repeat(stmt="Create_Set()",number=1000,setup="from __main__ import Create_Set", repeat=30)
print("The Time of Create_Set : {}".format(sum(t)/len(t)))
print("\n")
t = timeit.repeat(stmt="Test_List()",number=1000,setup="from __main__ import Test_List", repeat=30)
print("The Time of Test_List : {}".format(sum(t)/len(t)))
t = timeit.repeat(stmt="Test_Tuple()",number=1000,setup="from __main__ import Test_Tuple", repeat=30)
print("The Time of Test_Tuple : {}".format(sum(t)/len(t)))
t = timeit.repeat(stmt="Test_Set()",number=1000,setup="from __main__ import Test_Set", repeat=30)
print("The Time of Test_Set : {}".format(sum(t)/len(t)))
print("\nThe end")
最后,我发现:
Size: Set > Tuple > List
Speed: List > Tuple > Set
我认为我的测试代码是错误的。它出什么问题了?
我更改了测试代码:
List_Test = list(range(500000))
......
def Test_List():
randomNumber = random.randint(0,500000)
for i in List_Test:
if i == randomNumber:
break
# Other test code is the same
测试的结果总是list≈tuple> set
。
当将数字500000(x20)更改为10000000时,
它有时是list≈tuple≈set
,但经常是list≈tuple> set
。
May I infer that only when all of them have the same length(And the number of length is large),we can use set
(Although its size is much larger than tuple
and list
)?
问题来源: stackoverflow
这个测试套件有很多问题。
[range(1000)]
不等同于其他两个声明。这将形成一个包含一个元素的列表,并且该单个元素指向该范围。getsizeof不是递归的,因此它仅给出外部对象的大小。这可以通过创建具有不同范围大小的单个元素的列表并注意到getsizeof
调用始终给出相同的结果来说明。
如果使用list(range(1000))
,您将得到一个合理的结果,该结果与元组的大小大致相同。我不确定将这些列表设为1000后会获得什么信息-为什么不比较三个空元素的大小?即使在这里,就我所知,这基本上还是一个与实现有关的测试,实际上与如何编写Python程序没有太大关系。当然,set会比您期望的大一些(基于哈希的结构通常比列表具有更多的开销),并且版本之间会有所不同。
至于“创建”测试,请考虑`set(i for range(1000)中的i)。绝不会测试创建set所花费的时间,因为大部分时间都花在创建和运行作为参数传递的生成器上。与上一个测试一样,即使测试是公平的,我也不知道这能证明什么(即您使用了list()初始化方法而不是列表推导方法)。与“ size”测试一样,您可以使用空列表调用初始化程序,但是所有这些表明,创建时间实际上是相同的:存在一些函数调用和对象分配开销,这些开销是特定于实现的。
最后,对查找操作进行速度测试:
for i in Set_Test:
if i == 6:
break
这将对最佳情况进行硬编码。列表和元组查找执行线性搜索,因此始终在7个比较中找到目标。这将几乎与集合查找相同,后者为O(1),但需要一些复杂的哈希运算,这会增加开销。该测试应使用随机索引,其中的分布意味着列表和元组将定期遇到最坏情况的情况。该集合应胜过列表,并且元组正确完成。
此外,诸如“集合比列表快”这样的语句几乎没有意义-不能像这样对数据结构进行比较,“更快”之类的词表示特定的运行时条件,这些条件高度可变且区分大小写-具体。比较数据结构需要比较其操作的时间复杂度,这有助于描述它们是否适合某些目的。
总结一下:即使正确编写,前两个测试也不值得执行,最后一个测试将显示集合查找为O(1),而列表/元组查找为O(n)(如果使用随机目标项目使它们公平) 。
回答来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。