Python 中 + 和 += 赋值操作的性能比较

2024-04-18 09:58:19 浏览数 (2)

1. 问题背景

在 Python 中,我们可以通过 = 和 = … 完成累加操作,在实际开发过程中我们一般会优先选择 =,然而最近在对比 = 和 = … 的性能时出现了 = 反而更慢的现象。因此,我们决定对此问题进行深入探讨。

2. 解决方案

为了准确地评估 = 和 = … 的性能差异,我们编写了一个简单的测试脚本,封装了两个函数并使用 timeit 测试模块来测量它们的执行时间。

代码语言:python代码运行次数:0复制
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

if __name__ == '__main__':
    import timeit
    print(timeit.repeat("testAccumPlusEqual()",
                    setup="from __main__ import testAccumPlusEqual"))
    print(timeit.repeat("testAccumEqualPlus()",
                    setup="from __main__ import testAccumEqualPlus"))

测试结果显示,在我们的测试环境下,= … 比 = 的执行速度更快。为了进一步探究原因,我们使用 dis 模块来查看这两个函数的字节码:

代码语言:python代码运行次数:0复制
>>> 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 指令。两者之间的区别在于,INPLACE_ADD 会直接修改操作数的值,而 BINARY_ADD 则会创建一个新的对象。因此, = 操作需要花费更多的时间来更新操作数的值。

综合以上分析,我们可以得出结论,在 Python 中,= … 比 = 的执行速度更快,原因在于 = 使用 INPLACE_ADD 指令,直接修改操作数的值,而 = … 使用 BINARY_ADD 指令,创建一个新的对象。

0 人点赞