Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Python';s的集合差分方法是否需要空集合的时间?_Python_Performance_Set_Operators - Fatal编程技术网

为什么Python';s的集合差分方法是否需要空集合的时间?

为什么Python';s的集合差分方法是否需要空集合的时间?,python,performance,set,operators,Python,Performance,Set,Operators,我的意思是: > python -m timeit "set().difference(xrange(0,10))" 1000000 loops, best of 3: 0.624 usec per loop > python -m timeit "set().difference(xrange(0,10**4))" 10000 loops, best of 3: 170 usec per loop 显然,python会遍历整个参数,即使事先知道结果是空集。有什么好的理由吗

我的意思是:

> python -m timeit "set().difference(xrange(0,10))"   
1000000 loops, best of 3: 0.624 usec per loop

> python -m timeit "set().difference(xrange(0,10**4))"
10000 loops, best of 3: 170 usec per loop
显然,python会遍历整个参数,即使事先知道结果是空集。有什么好的理由吗?代码是在Python2.7.6中运行的


(即使对于非空集合,如果您发现在迭代过程中删除了第一个集合的所有元素,也应该立即停止。)

IMO这是一个专业化的问题,请考虑:

In [18]: r = range(10 ** 4)

In [19]: s = set(range(10 ** 4))

In [20]: %time set().difference(r)
CPU times: user 387 µs, sys: 0 ns, total: 387 µs
Wall time: 394 µs
Out[20]: set()

In [21]: %time set().difference(s)
CPU times: user 10 µs, sys: 8 µs, total: 18 µs
Wall time: 16.2 µs
Out[21]: set()
显然,这个差异专门实现了
set-set

请注意,差分运算符要求右侧参数为集合,而差分运算符允许任何iterable


Per@wim实现在

当Python核心开发人员添加新特性时,首要任务是正确的代码和全面的测试覆盖率。这本身就够难的了。当有人有了想法和倾向时,加速往往会来得晚。我打开了一个跟踪问题,总结了这里讨论的建议和反对理由。我将在这里总结一下它的配置

更新:3.6.0b1中增加了一个开始为空的集合的早期输出,大约在一天内到期

有什么好的理由吗

为空集合设置一个特殊路径以前从未出现过

即使对于非空集,如果您发现在迭代的中途删除了第一个集的所有元素,那么立即停止也是有意义的

这是一个合理的优化要求。我已经做了一个测试,很快就会应用它。以下是应用修补程序后的新计时:

 $ py -m timeit -s "r = range(10 ** 4); s = set()" "s.difference(r)"
10000000 loops, best of 3: 0.104 usec per loop
 $ py -m timeit -s "r = set(range(10 ** 4)); s = set()" "s.difference(r)"
10000000 loops, best of 3: 0.105 usec per loop
 $ py -m timeit -s "r = range(10 ** 4); s = set()" "s.difference_update(r)"
10000000 loops, best of 3: 0.0659 usec per loop
 $ py -m timeit -s "r = set(range(10 ** 4)); s = set()" "s.difference_update(r)"
10000000 loops, best of 3: 0.0684 usec per loop

在Python3中甚至更慢:)我想python的制作者没有想到这一点,因为在现实生活中这种情况不应该经常发生。解决方法:在运行差异之前检查设置大小。但是很好!顺便说一句,最近的PyPy也是如此。@Jean-Françoisfare即使对于非空集,如果您发现在迭代过程中删除了第一个集的所有元素,立即停止也是有意义的。我不确定这是否是一个好的理由,但
set.difference
的参数是任意的可数,不仅仅是布景。迭代某些函数的行为可能会产生副作用,让函数在所有情况下都保证相同的行为可能更重要,而不是只在一种情况下让参数“未使用”。特例很好!因此,空集的案例被补丁覆盖。另一个呢?例如,
s=set([1])
r=set(range(10**4))
。我用
r
s
做了一个简单的测试,就像我上次的评论一样,显然当这两个集合都是集合时,它的运行速度非常快,即使第一个集合不是空的。@RaymondHettinger新的实现将保证迭代器总是被完全使用,还是会被保留为未定义?