我使用比较两种不同的_accumulator_
方式timeit.repeat
进行了一些快速基准测试。
def testAccumPlusEqual():
x = 0
for i in range(100):
x += 1
return x
def testAccumEqualPlus():
x = 0
for i in range(100):
x = x + 1
return x
我对timeit.repeat
的实现是:
if __name__ == '__main__':
import timeit
print(timeit.repeat("testAccumPlusEqual()",
setup="from __main__ import testAccumPlusEqual"))
print(timeit.repeat("testAccumEqualPlus()",
setup="from __main__ import testAccumEqualPlus"))
结果如下:
>>>
[8.824021608811469, 8.80440620087051, 8.791231916848997]
[8.101681307351758, 8.143080002052649, 8.181129610882778]
诚然,在宏伟的计划中,这种时差可能并不明显,但如果大规模使用,可能会导致减速。所以我想我真的在问:
从我所见过的任何地方来看,事实上的标准是积累+=
,但事实仍然如此吗?
为什么+=
的表现会比x=x+
差?
注意:在Windows 7 64位上使用CPython 3.3.2(使用32位版本的python)
这实际上不是一个答案,但它可以帮助你理解Python代码中发生了什么。您可以在两个函数上调用 dis 并获取:
>>> import dis
>>> dis.dis(testAccumEqualPlus)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 30 (to 39)
9 LOAD_GLOBAL 0 (range)
12 LOAD_CONST 2 (100)
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 16 (to 38)
22 STORE_FAST 1 (i)
4 25 LOAD_FAST 0 (x)
28 LOAD_CONST 3 (1)
31 BINARY_ADD
32 STORE_FAST 0 (x)
35 JUMP_ABSOLUTE 19
>> 38 POP_BLOCK
5 >> 39 LOAD_FAST 0 (x)
42 RETURN_VALUE
>>> dis.dis(testAccumPlusEqual)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 30 (to 39)
9 LOAD_GLOBAL 0 (range)
12 LOAD_CONST 2 (100)
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 16 (to 38)
22 STORE_FAST 1 (i)
4 25 LOAD_FAST 0 (x)
28 LOAD_CONST 3 (1)
31 INPLACE_ADD
32 STORE_FAST 0 (x)
35 JUMP_ABSOLUTE 19
>> 38 POP_BLOCK
5 >> 39 LOAD_FAST 0 (x)
42 RETURN_VALUE
如您所见,唯一的区别是+=
INPLACE_ADD
和= .. +
BINARY_ADD