Counter()+=Counter和Counter.update(Counter哪个更快?

1 投票
1 回答
861 浏览
提问于 2025-04-17 22:34

哪个更快? Counter()+=Counter 还是 Counter.update(Counter)?

为什么其中一个会比另一个快?

我尝试了一些简单的性能测试,但我觉得这还不足以明确说明 Counter+=CounterCounter.update(Counter) 更快:

from collections import Counter
import time
x = Counter(['abc','def', 'abc'])
y = Counter(['xyz', 'xyz', 'uvw', 'abc'])

start = time.time()
x.update(y)
end = time.time() - start
print x
print 'update:', end
print 

x = Counter(['abc','def', 'abc'])
start = time.time()
x+=y
end = time.time() - start
print x
print 'plus:', end

[输出]:

Counter({'abc': 3, 'xyz': 2, 'def': 1, 'uvw': 1})
update: 4.48226928711e-05

Counter({'abc': 3, 'xyz': 2, 'def': 1, 'uvw': 1})
plus: 2.28881835938e-05

1 个回答

2

Counter.update() 方法的设计是为了更快。相比之下,__add__() 方法需要做更多的工作,因为它还要处理非负值的问题:

# heart of the update() loop in Python 2:
for elem, count in iterable.iteritems():
    self[elem] = self_get(elem, 0) + count

# heart of the __add__() loop in Python 2:
result = Counter()
for elem, count in self.items():
    newcount = count + other[elem]
    if newcount > 0:
        result[elem] = newcount
for elem, count in other.items():
    if elem not in self and count > 0:
        result[elem] = count
return result

正如你所看到的,__add__ 方法的工作量明显更大。

在后来的 Python 3 版本中,还有一个不同之处,就是出现了 __iadd__() 方法,它可以进行真正的原地更新,这样的工作量比 __add__() 方法要少,因为后者会创建一个新的计数器,然后再用这个新计数器替换掉旧的计数器:

def __iadd__(self, other):
    for elem, count in other.items():
        self[elem] += count
    return self._keep_positive()

撰写回答