Python 根据参数类型设置IsubSet性能差异
为什么要问这个问题? 我试着回答这个问题:对于Python 根据参数类型设置IsubSet性能差异,python,performance,set,Python,Performance,Set,为什么要问这个问题? 我试着回答这个问题:对于all(python循环,即使是在理解中,也会比某些函数执行的隐式循环慢一些)来说,它比生成器理解更好: 其中,bar是一个字典,foo是一个列表,使用set.issubset(将foo转换为set,以便能够使用foo.issubset(bar)),但未能成功击败all解决方案(除非两个容器都转换为sets) 我的问题: 根据以下文件: 注意,union()、intersection()、difference()和symmetric_differen
all
(python循环,即使是在理解中,也会比某些函数执行的隐式循环慢一些)来说,它比生成器理解更好:
其中,bar
是一个字典,foo
是一个列表,使用set.issubset
(将foo
转换为set
,以便能够使用foo.issubset(bar)
),但未能成功击败all
解决方案(除非两个容器都转换为set
s)
我的问题:
根据以下文件:
注意,union()、intersection()、difference()和symmetric_difference()、issubset()和issuperset()方法的非运算符版本将接受任何iterable作为参数。相反,它们基于运算符的对应项要求它们的参数是集合。这就排除了像set('abc')和'cbs'这样容易出错的构造,以利于更具可读性的set('abc')。intersection('cbs')
好的,但是性能实际上取决于参数的类型,即使复杂性不是():
我的结果(Python 3.4):
因此,如果将集
作为参数传递,则结果非常快
使用列表
要慢得多。我发现这是因为必须在字符串上进行哈希运算的代价很高。因此,我用如下整数更改了测试输入:
foo = {i for i in range(1, 10000, 2)}
bar = foo - {400}
结果在全球范围内更快,但仍然存在巨大的时差:
issubset(set) 0.5981848205989139
issubset(list) 1.7991591232742143
issubset(dict) 1.889119736960271
issubset(dict_keys) 2.2531574114632678
我还尝试通过dict.keys()
更改dict
,就像在python 3中一样,这些键被称为()“一个类似集合或无序的容器对象”
但在这种情况下,结果甚至比使用dict
或list
更糟糕
那么,为什么传递一个集合
会胜过传递一个列表
或dict
或dict\u keys
对象?我在文档中没有看到任何关于这方面的内容。需要一个集合来处理(冻结集和子类计数);如果你把别的东西传给它,它就会成为一组。它基本上是all(elem in other for elem in self)
,它需要知道elem in other
是有效的,并且意味着它对集合的意义。它知道如何保证这一点的唯一方法是确保other
是一个集合。制作一套很昂贵
(我已经略过了一些细节。如果你想知道到底发生了什么,特别是如果你有一个奇怪的集合子类,请阅读链接中的源代码。)请使用
timeit
进行基准测试,使用time.time()
的增量进行基准测试是不可靠的。@wim done。我可能缺乏进行cleartimeit
基准测试的经验。结果是可比较的。我希望它可能可以与dict键视图(设置得足够像)一起工作,但还没有人费心在CPython中实现它。似乎PyAnySet\u Check
允许使用frozenset和set子类。@Jean-Françoisfare:正如wim所说,frozenset
s在本次检查中计为集合。(相同的例程用于set.issubset
和frozenset.issubset
,并且无论self
的类型如何,它都接受相同的参数类型)
issubset(set) 1.6141405847648826
issubset(list) 3.698748032058883
issubset(dict) 3.6300025109004244
issubset(dict_keys) 4.224299651223102
foo = {i for i in range(1, 10000, 2)}
bar = foo - {400}
issubset(set) 0.5981848205989139
issubset(list) 1.7991591232742143
issubset(dict) 1.889119736960271
issubset(dict_keys) 2.2531574114632678