为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Counter.__iadd__ 比 Counter.update 慢那么多?

为什么 Counter.__iadd__ 比 Counter.update 慢那么多?

四季花海 2023-02-22 10:56:59
我试验Counter.__iadd__并Counter.update累积了 10,000 个计数器,结果证明__iadd__需要 1.8 秒才能完成,而update只需要 36 毫秒。我想知道为什么__iadd__要花这么多时间。我猜它首先创建一个新对象并将该对象复制到自身。但它为什么要这样做呢?不是到位了吗?我不知道为什么它不使用与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 msWall 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 sWall time: 1.8 s
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

你的假设是不正确的。__iadd__不会创建新的计数器。

速度变慢是因为多重集运算符collections.Counter 过滤掉了非正计数的条目,这需要每次都遍历整个计数器:

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

update不那样做。

此外,__iadd__是一个用于覆盖+=行为的挂钩。您几乎不应该手动调用它;你应该使用+=(或者update,在这种情况下,或者只是a[i] += 1)。


查看完整回答
反对 回复 2023-02-22
  • 1 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号