Python 为什么Counter.iadd比Counter.update慢得多?

Python 为什么Counter.iadd比Counter.update慢得多?,python,python-3.x,Python,Python 3.x,我用计数器进行了实验。和计数器。更新以累积10000个计数器,结果表明\uu\iadd\uu需要1.8秒,而更新只需要36毫秒 我想知道为什么花这么多时间。我猜它首先创建一个新对象,然后将该对象复制到自身。但为什么会这样呢?它不在原地吗?我不知道为什么它不使用与update相同的实现 以下是我在IPython的实验: [ins] In [11]: def update(): ...: a = Counter() ...: for i in

我用
计数器进行了实验。
计数器。更新
以累积10000个计数器,结果表明
\uu\iadd\uu
需要1.8秒,而
更新
只需要36毫秒

我想知道为什么花这么多时间。我猜它首先创建一个新对象,然后将该对象复制到自身。但为什么会这样呢?它不在原地吗?我不知道为什么它不使用与
update
相同的实现

以下是我在IPython的实验:

[ins] In [11]: def update():
          ...:     a = Counter()
          ...:     for i in range(10000):
          ...:         a.update(Counter([i]))
          ...:
          ...: %time update()
CPU times: user 36 ms, sys: 0 ns, total: 36 ms
Wall time: 33.3 ms

[nav] In [12]: def iadd():
          ...:     a = Counter()
          ...:     for i in range(10000):
          ...:         a.__iadd__(Counter([i]))
          ...:
          ...: %time iadd()
CPU times: user 1.8 s, sys: 0 ns, total: 1.8 s
Wall time: 1.8 s

你的假设是错误的<代码>\uuuu iadd\uuuu不创建新计数器

发生减速的原因是
collections.Counter
中的多集运算符,这需要每次迭代整个计数器:

提供了几种数学运算,用于组合计数器对象以生成多集(计数大于零的计数器)。加法和减法通过增加或减少相应元素的计数来组合计数器。交集和并集返回相应计数的最小值和最大值。每个操作都可以接受带符号计数的输入,但输出将排除计数为零或更少的结果

update
不会这样做

另外,
\uuu iadd\uuu
是一个钩子,用于覆盖
+=
行为。你几乎不应该手动调用它;您应该使用
+=
(或者在本例中使用
更新
,或者只使用
a[i]+=1