Skip to content

Instantly share code, notes, and snippets.

@westhood
Last active December 15, 2015 13:59
Show Gist options
  • Select an option

  • Save westhood/5271478 to your computer and use it in GitHub Desktop.

Select an option

Save westhood/5271478 to your computer and use it in GitHub Desktop.
为什么 while 1:pass 要比 while True: pass 快

今天看到一个帖子说 pythonwhile 1: pass 要比 while True: pass 速度更快。

第一感觉是有点反直觉。 while 1: pass 貌似应等价于 while bool(1): pass , 怎么也要比 while True: pass 多一次转换的调用。

于是做了一个简单的实验,

In [1]: timeit while True: break
10000000 loops, best of 3: 109 ns per loop

In [2]: timeit while 1: break
10000000 loops, best of 3: 54.2 ns per loop

while 1: passwhile True: pass 快了近一倍。看来是对所谓的 bool 转换的的理解有误,需要在字节码级别一探究竟。

In [3]: def foo():
   ...:     while 1:
   ...:         break
   
In [6]: dis.dis(foo)
  2           0 SETUP_LOOP               4 (to 7)   

  3     >>    3 BREAK_LOOP
              4 JUMP_ABSOLUTE            3
        >>    7 LOAD_CONST               0 (None)
             10 RETURN_VALUE
             
In [7]: def foo():
    while True:
        break
   ...:

In [8]: dis.dis(foo)
  2           0 SETUP_LOOP              11 (to 14)
        >>    3 LOAD_GLOBAL              0 (True)
              6 POP_JUMP_IF_FALSE       13

  3           9 BREAK_LOOP
             10 JUMP_ABSOLUTE            3
        >>   13 POP_BLOCK
        >>   14 LOAD_CONST               0 (None)
             17 RETURN_VALUE

dis 模块做一下反编译, 两者的区别就很明显了。 while 1: 实际上被编译器完全优化掉了, 而 while True: 则需要 load 一个全局变量 True 后再做一次 test 。TrueFalse 虽然在很多 IDE 或 Editor 里面都被高亮为常量 :),但在 python 里并不是 Literal , 只是 builtin 里两个类型为 bool 的普通全局变量而已。 虽然 True = 0 很愚蠢, 但没人可以阻止你这样做。

最后附上一些 python 操作的字节码,算是对一些常见 python 操作效率区别的解释吧。

In [21]: def swap(x, y):
   ....:     temp = x
   ....:     x = y
   ....:     y = temp
   ....:

In [22]: dis.dis(swap)
  2           0 LOAD_FAST                0 (x)
              3 STORE_FAST               2 (temp)

  3           6 LOAD_FAST                1 (y)
              9 STORE_FAST               0 (x)

  4          12 LOAD_FAST                2 (temp)
             15 STORE_FAST               1 (y)
             18 LOAD_CONST               0 (None)
             21 RETURN_VALUE  


In [19]: def swap(x, y):
    x, y = y, x
   ....:

In [20]: dis.dis(swap)
  2           0 LOAD_FAST                1 (y)
              3 LOAD_FAST                0 (x)
              6 ROT_TWO
              7 STORE_FAST               0 (x)
             10 STORE_FAST               1 (y)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE 

In [23]: def swap(x, y, z):
    x, y, z = y, z, x
   ....:

In [24]: dis.dis(swap)
  2           0 LOAD_FAST                1 (y)
              3 LOAD_FAST                2 (z)
              6 LOAD_FAST                0 (x)
              9 ROT_THREE
             10 ROT_TWO
             11 STORE_FAST               0 (x)
             14 STORE_FAST               1 (y)
             17 STORE_FAST               2 (z)
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE            

In [25]: def swap(a, b, c, d):
    a, b, c, d  = b, c, d, a
   ....:

In [26]: dis.dis(swap)
  2           0 LOAD_FAST                1 (b)
              3 LOAD_FAST                2 (c)
              6 LOAD_FAST                3 (d)
              9 LOAD_FAST                0 (a)
             12 BUILD_TUPLE              4
             15 UNPACK_SEQUENCE          4
             18 STORE_FAST               0 (a)
             21 STORE_FAST               1 (b)
             24 STORE_FAST               2 (c)
             27 STORE_FAST               3 (d)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment