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。我可能缺乏进行clear
timeit
基准测试的经验。结果是可比较的。我希望它可能可以与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