“extend”比“+=”更快吗?

11

在Python中,我们有两种方法可以连接列表:

  1. lst.extend(another_lst)
  2. lst += another_lst

我以为使用extend比使用+=更快,因为它重用了列表而不是使用另外两个创建新列表。

但是当我用timeit进行测试时,结果表明+=更快。

>>> timeit('l.extend(x)', 'l = range(10); x = range(10)')
0.16929602623
>>> timeit('l += x', 'l = range(10); x = range(10)')
0.15030503273
>>> timeit('l.extend(x)', 'l = range(500); x = range(100)')
0.805264949799
>>> timeit('l += x', 'l = range(500); x = range(100)')
0.750471830368

timeit中的代码有问题吗?


4
为什么+=需要创建一个新列表?你是不是把它和+混淆了? - kennytm
1
你可以使用 L'li 作为示例列表的名称吗?在某些字体中,l 看起来像 1 - tshepang
2
@Tshepang:你知道你可以在浏览器中配置字体偏好设置吗? - SilentGhost
3
@Silent,我知道。但是最好取消这种需要,特别是因为我的设置是默认的(“允许页面选择它们自己的字体”)。 - tshepang
4
以下是解释 += 运算符重载的答案链接:https://dev59.com/Q3E95IYBdhLWcg3wWMlQ#2347423。 - Scott Griffiths
显示剩余11条评论
1个回答

18

编辑:我已经测试了性能,无法复制任何显着的差异。


这是字节码 - 感谢@John Machin指出不一致之处。

>>> import dis
>>> l = [1,2,3]
>>> m = [4,5,6]
>>> def f1(l, m):
...     l.extend(m)
...
>>> def f2(l,m):
...     l += m
...
>>> dis.dis(f1)
  2           0 LOAD_FAST                0 (l)
              3 LOAD_ATTR                0 (extend)
              6 LOAD_FAST                1 (m)
              9 CALL_FUNCTION            1
             12 POP_TOP
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE
>>> dis.dis(f2)
  2           0 LOAD_FAST                0 (l)
              3 LOAD_FAST                1 (m)
              6 INPLACE_ADD
              7 STORE_FAST               0 (l)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

注意,extend使用的是CALL_FUNCTION而不是INPLACE_ADD。任何微小的性能差异可能都可以归因于此。


@Constantin,我想主要是属性查找。 INPLACE_ADD 只是将对象上定义的任何 __iadd__ 方法路由到它。 - aaronasterling
@katriealex,@Constantin,@aaronsterling:天哪,这个是LOAD_ATTR和CALL_FUNCTION,而不是INPLACE_ADD和STORE_FAST。 - John Machin
@katriealex:增加了混淆的程度,你的列表在一种情况下是全局的,在另一种情况下是局部的。考虑使用具有相同开销的最小示例,例如在这种情况下 def f1(a, b): a.extend(b)def f2(a, b): a += b - John Machin
@katrielalex 我在我的系统上得到的比例与 OP 差不多。 - aaronasterling
@John,为什么你在解释速度差异时如此强调STORE_FAST?似乎如果有什么作用的话,它会对+=不利,因为它所扮演的角色甚至在使用“extend”时也是不必要的。 - aaronasterling
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接