【问题标题】:Python: multiple assignment vs. individual assignment speedPython:多重赋值与单独赋值速度
【发布时间】:2014-04-12 06:55:52
【问题描述】:

我一直希望从我的代码中获得更多性能;最近,在浏览this Python wiki page时,我发现了这个说法:

多重赋值比单独赋值慢。例如“x,y=a,b”比“x=a; y=b”慢。

很好奇,我测试了它(在 Python 2.7 上):

$ python -m timeit "x, y = 1.2, -1.4"
10000000 loops, best of 3: 0.0365 usec per loop

$ python -m timeit "x = 1.2" "y = -1.4"
10000000 loops, best of 3: 0.0542 usec per loop

我重复了几次,以不同的顺序等,但多次分配 sn-p 始终比单独分配好至少 30%。显然,我的代码中涉及变量赋值的部分不会成为任何重大瓶颈的根源,但我的好奇心还是被激起了。当文档另有说明时,为什么多次分配明显比单独分配快?

编辑:

我测试了对两个以上变量的赋值,得到了以下结果:

趋势似乎或多或少是一致的;谁能重现它?

(CPU:Intel Core i7 @ 2.20GHz)

【问题讨论】:

  • 对于 Python 2.7.5,我看不到与您的一致的结果。我看到多个分配 @ 0.0494 usec/loop 和单独分配 @ 0.0452 usec/loop。
  • 这里是 Python 2.7.4 Ubuntu 13.04。我能够重现该问题,但在 Python 3.3.2 中,我不能。
  • Python 2.7.6 给出了与 OP 类似的发现。 Python 3.3 给出了更接近(0.49 和 0.55)的读数。
  • 362 与 Python 2.7.3 中的 453。我认为 Python 3.4 ~250 没有区别

标签: python performance variable-assignment timeit python-internals


【解决方案1】:

有趣的是,它可能在某种程度上取决于 CPU。这些都是 64 位 linux 机器(相同的 Python 版本)。

Intel(R) Core(TM)2 Duo CPU T7300 @ 2.00GHz 的结果

$ python -V
Python 2.7.5+
$ python -m timeit "x, y = 1.2, -1.4"
10000000 loops, best of 3: 0.0554 usec per loop
$ python -m timeit "x = 1.2" "y = -1.4"
10000000 loops, best of 3: 0.0349 usec per loop

Intel(R) Pentium(R) CPU G850 @ 2.90GHz 的结果

$ python -V
Python 2.7.5+
$ python -m timeit "x, y = 1.2, -1.4"
10000000 loops, best of 3: 0.0245 usec per loop
$ python -m timeit "x = 1.2" "y = -1.4"
10000000 loops, best of 3: 0.0394 usec per loop

【讨论】:

    【解决方案2】:

    最好看一下python的dis模块。哪个反汇编字节码。测试显示两个变量赋值:

    import dis 
    
    def single_assignment():
        x = 1 
        y = 2 
    
    def multiple_assignment():
        x, y = 1, 2
    
    print dis.dis(single_assignment)
    print dis.dis(multiple_assignment)
    

    字节码:

      4           0 LOAD_CONST               1 (1)
                  3 STORE_FAST               0 (x)
    
      5           6 LOAD_CONST               2 (2)
                  9 STORE_FAST               1 (y)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE        
    None
      8           0 LOAD_CONST               3 ((1, 2))
                  3 UNPACK_SEQUENCE          2
                  6 STORE_FAST               0 (x)
                  9 STORE_FAST               1 (y)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE        
    None
    

    看起来需要的字节码数量在 2 个变量的情况下是相同的。如果有 3 个或更多变量分配,则字节码的数量会更小。

    【讨论】:

    • 字节码指令的数量不是一个很好的性能指标。
    • 我可以发誓这是窥视孔优化器应该捕获的情况之一。
    • 这说明使用常量并不是最好的测试;测试应该使用变量来完成; x, y = a, b,而不是 x, y = 1, 2。哦,dis.dis() 已经使用了print,并返回None;在此处从您的脚本中删除您的 prints。
    猜你喜欢
    • 2020-01-16
    • 2021-03-30
    • 1970-01-01
    • 2023-03-04
    • 2018-08-13
    • 1970-01-01
    • 2020-08-10
    • 2015-09-18
    相关资源
    最近更新 更多