0

我通过timeit.repeat比较两种不同的使用_accumulator_.

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)

4

1 回答 1

2

这实际上不是一个答案,但它可以帮助您了解 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_ADDfor+=BINARY_ADDfor= .. +

于 2013-09-15T17:52:06.513 回答