而(1)比。 for while(真) – 为什么会有差异?
在这个关于perl中的无限循环的问题中有所提及: while(1)Vs. for(;;)有速度差吗? ,我决定在Python中运行一个类似的比较。 我期望编译器会为while(True): pass
和while(1): pass
生成相同的字节码,但实际上在python2.7中并不是这样。
以下脚本:
import dis def while_one(): while 1: pass def while_true(): while True: pass print("while 1") print("----------------------------") dis.dis(while_one) print("while True") print("----------------------------") dis.dis(while_true)
产生以下结果:
while 1 ---------------------------- 4 0 SETUP_LOOP 3 (to 6) 5 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE while True ---------------------------- 8 0 SETUP_LOOP 12 (to 15) >> 3 LOAD_GLOBAL 0 (True) 6 JUMP_IF_FALSE 4 (to 13) 9 POP_TOP 9 10 JUMP_ABSOLUTE 3 >> 13 POP_TOP 14 POP_BLOCK >> 15 LOAD_CONST 0 (None) 18 RETURN_VALUE
while True
使用显然更复杂。 为什么是这样?
在其他上下文中,python的行为就像True
等于1:
>>> True == 1 True >>> True + True 2
为什么while
区分两者?
我注意到python3使用相同的操作来评估语句:
while 1 ---------------------------- 4 0 SETUP_LOOP 3 (to 6) 5 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE while True ---------------------------- 8 0 SETUP_LOOP 3 (to 6) 9 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE
python3有没有改变,以评估布尔值的方式?
在Python 2.x中, True
不是关键字,而是一个内置的全局常量 ,在bool
types中定义为1。 所以解释器还是要加载True
的内容。 换句话说, True
是可重新分配的:
Python 2.7 (r27:82508, Jul 3 2010, 21:12:11) [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> True = 4 >>> True 4
在Python 3.x中它确实成为一个关键字和一个真正的常量:
Python 3.1.2 (r312:79147, Jul 19 2010, 21:03:37) [GCC 4.2.1 (Apple Inc. build 5664)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> True = 4 File "<stdin>", line 1 SyntaxError: assignment to keyword
因此解释器可以用无限循环取代while True:
循环。
这不太对,
因此解释器可以用无限循环取代True:循环。
因为人们仍然可以跳出循环。 但是确实,这样一个循环的else
子句永远不会在Python 3中被访问。同样,简化值查找也是事实,使得它在Python 2中运行得和while 1
一样快。
性能比较
演示一个稍微不重要的while循环的时间差异:
build立
def while1(): x = 0 while 1: x += 1 if x == 10: break def whileTrue(): x = 0 while True: x += 1 if x == 10: break
Python 2
>>> import timeit >>> min(timeit.repeat(while1)) 0.49712109565734863 >>> min(timeit.repeat(whileTrue)) 0.756627082824707
Python 3
>>> import timeit >>> min(timeit.repeat(while1)) 0.6462970309949014 >>> min(timeit.repeat(whileTrue)) 0.6450748789939098
说明
为了解释这个区别,在Python 2中:
>>> import keyword >>> 'True' in keyword.kwlist False
但在Python 3中:
>>> import keyword >>> 'True' in keyword.kwlist True >>> True = 'true?' File "<stdin>", line 1 SyntaxError: can't assign to keyword
由于True
是Python 3中的一个关键字,因此解释器不必查找该值是否有人用其他值replace它。 但是,由于可以将True
分配给另一个值,因此解释者每次都必须查看它。
Python 2的结论
如果你在Python 2中有一个紧密的,长期运行的循环,你可能应该使用while 1:
而不是while True:
Python 3的结论
使用的while True:
如果你没有条件打破你的循环。