Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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 “in”在“包含”以上有多少优化?_Python_Python 3.x - Fatal编程技术网

Python “in”在“包含”以上有多少优化?

Python “in”在“包含”以上有多少优化?,python,python-3.x,Python,Python 3.x,因此,在itertools配方部分,他们有一段代码,如下所示: seen = set() seen_add = seen.add 我想知道类似的想法是否可以弥补中的和\uuuuu包含的

因此,在itertools配方部分,他们有一段代码,如下所示:

seen = set()
seen_add = seen.add
我想知道类似的想法是否可以弥补
中的
\uuuuu包含的
之间的性能差距。例如,使用以下代码:

seen = set()
seen_add = seen.add
in_seen = seen.__contains__
for item in iterable:
    in_seen(item)
vs

因此,如果我正确地读取了dis的输出,问题就归结为“y中的x比func(x)
快吗?”


编辑:对于那些说这无关紧要的人,我并没有把它当作优化。我试图通过分离这个元素来更好地理解这种语言。

中的
似乎更快。据猜测,
COMPARE\u OP
CALL\u函数
更有效,因为它知道它有多少个参数

haugh@~$ python3 -m timeit -s "l = {1}" "2 in l"
10000000 loops, best of 3: 0.029 usec per loop

haugh@~$ python3 -m timeit -s "l = {1}" "l.__contains__(2)"
10000000 loops, best of 3: 0.0612 usec per loop

haugh@~$ python3 -m timeit -s "l = {1}; isin=l.__contains__" "isin(2)"
10000000 loops, best of 3: 0.0301 usec per loop

我们最多只能说几十纳秒,所以通常情况下这并不重要。而且,即使是这样,事情也比第一次出现时复杂得多


预绑定
seen.\uu包含
seen.\uu包含
seen.\uu包含
seen将比调用
seen加快速度。\uu包含
,但不只是在seen
中使用(更明显、更惯用的)

那么,为什么这与看到的不同呢

对于
seen.add()
,您显式地创建和调用绑定方法,这是无法避免的。因此,创建绑定方法一次,而不是每次…通常仍然不值得,但在那些罕见的情况下,当您需要节省纳秒时,这是一个胜利

在seen
中的
中,您没有显式地创建绑定方法,您只是在计算运算符。在CPython中,如果
seen
是一个Python类的实例,那么它将隐式创建一个绑定方法,但是如果它是一个内置类的实例,它将直接在C插槽中查找该方法并调用该方法。因此,虽然通过一次而不是一次又一次地创建绑定方法来节省时间,但仍然没有通过绑定方法而不是直接调用C函数所浪费的时间那么多

当然,在不同的Python实现中,或者只是使用不同的类型(不是内置的),情况可能会有所不同


如果这真的很重要(通常不会),那么您当然应该使用您关心的平台、Python实现和类型来测试它

但是,仅作为一个示例,我将在MacBook Pro上使用64位python.org CPython 3.7和
set
对其进行测试:

In [778]: s = {1, 2, 3}
In [779]: sc = s.__contains__
In [780]: %timeit 4 in s
33.9 ns ± 0.444 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [781]: %timeit s.__contains__(4)
69.3 ns ± 0.936 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [782]: %timeit sc(4)
47.6 ns ± 0.866 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
正如所料,
sc
收回了我们浪费的一些时间,但不是全部时间

但是对于纯Python类型:

In [787]: class Set:
     ...:     def __contains__(self, n):
     ...:         return 1 <= n < 4
In [788]: s = Set()
In [789]: sc = s.__contains__
In [790]: %timeit 4 in s
129 ns ± 5.69 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [791]: %timeit s.__contains__(4)
124 ns ± 1.14 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [792]: %timeit sc(4)
108 ns ± 1.19 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
[787]中的
:类集合:
…:def_uuu包含(self,n):

…:返回1您测量过这个吗?听起来像是微优化。谁在乎?我在乎主要是出于好奇。我并不是真的关心代码中的这一点,但我认为分析这类事情很有趣。
in
调用
\uuuu包含\uuu
。在
seed\u add
中,节省了案例方法查找时间。我记得有一次我在一段执行量很大的代码上对几个方法应用了这种方法,并获得了约5%的性能提升。如果这在应用程序中产生了显著的差异,那么Python可能不是正确的语言。Python特别有价值,因为开发人员不需要花太多时间担心这种细节。它不是一种高性能的语言,但应该在与开发时间相比是一种可接受的权衡的情况下使用。这并不能真正回答问题。这里有额外的属性查找。关键是在所有条件相同的情况下比较它们。@gabeapleton查找什么额外的属性?数据结构不应该对@wim有影响,因为它在所有示例中都使用。正在比较的是
\uuuuu contains\uuuu
调用方法,直接或使用
in
运算符keyword@nosklo这可能不会改变绝对差异,但可以改变相对差异。@PatrickHaugh查找对象的属性总是比查找变量慢。例如,
seen.\uuuu包含\uuuu
快速生成
LOAD\u(seen);加载属性(添加)
,而在所见的中加载属性(添加)
只是
LOAD\u FAST(在所见的中)
@gabeapleton
%timeit
魔术只是替代默认交互式REPL的众多原因之一。@wim确实如此。我不厌其烦地不仅解释,甚至证明结果取决于这些事情。不切实际的数据集根本不重要;第一个数据结构中的散列和第二个数据结构中的链式比较都不会与一百万个元素而不是3个元素有显著区别。在这种情况下,它就在python文档中:(search unique_everseen)有趣的是,我开始阅读答案,我知道作者是谁。好极了usual@wim我确实想阻止人们不假思索地使用这些技巧。但我认为答案是,即使在同一个Python实现中,你如何得到两个相似的值的相反结果,而且如果你想考虑微优化的话,你需要考虑的所有复杂性都是一个更好的解决方案。
In [787]: class Set:
     ...:     def __contains__(self, n):
     ...:         return 1 <= n < 4
In [788]: s = Set()
In [789]: sc = s.__contains__
In [790]: %timeit 4 in s
129 ns ± 5.69 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [791]: %timeit s.__contains__(4)
124 ns ± 1.14 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [792]: %timeit sc(4)
108 ns ± 1.19 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)