我正在比较在python中将项目附加到列表的不同方法。我在我的计算机上测试过,结果当然会在其他计算机上有所不同。
选项1 :5.80秒只有50,000件商品!
a = []
for i in range(50000):
a = a + [i]
选项2 :2.27秒10,000,000项
a = []
for i in range(10000000):
a += [i]
选项3 :1.53秒10,000,000项
a = []
for i in range(10000000):
a.append(i)
选项1很慢并不奇怪,因为它每次都会创建一个新的列表副本。
使用扩充赋值运算符,选项2的速度要快得多。它会修改原始列表。
但选项3仍然明显更快。我期望使用append()方法和扩充赋值运算符来获得相同的结果。
为什么append()方法仍然比+ =运算符快得多?
PS: 我的python版本:
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32
根据taskino的回答,额外的开销是在每次循环迭代中创建一个新的列表对象[i]
引起的。这对我来说似乎很合理。我创建了新的测试代码,试图避免在每次迭代中创建一个新对象。是的,它现在更快,但仍然没有使用append()那么快,因为现在我又有额外分配的开销。但我认为它证明了taskinoor的重点。
选项4 :1.91秒10,000,000项 (备选方案2的改进版本)
a = []
b = [0]
for i in range(10000000):
b[0] = i
a += b
答案 0 :(得分:3)
第二种方法仍然需要创建临时列表[i]
。看看反汇编的代码:
>>> import dis
>>> def func_2(a, i):
... a += [i]
...
>>> def func_3(a, i):
... a.append(i)
...
>>> dis.dis(func_2)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (i)
6 BUILD_LIST 1
9 INPLACE_ADD
10 STORE_FAST 0 (a)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>> dis.dis(func_3)
2 0 LOAD_FAST 0 (a)
3 LOAD_ATTR 0 (append)
6 LOAD_FAST 1 (i)
9 CALL_FUNCTION 1
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>>
第二种方法需要6 BUILD_LIST
,但第三种方法不需要config.properties
。可能还有其他原因,但这应该是方法3更快的主要原因。