Why is if True slower than if 1?
为什么在python中
我试着学习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | >>> def test1(): ... if True: ... return 1 ... else: ... return 0 >>> print timeit("test1()", setup ="from __main__ import test1") 0.193144083023 >>> def test2(): ... if 1: ... return 1 ... else: ... return 0 >>> print timeit("test2()", setup ="from __main__ import test2") 0.162086009979 >>> def test3(): ... if True: ... return True ... else: ... return False >>> print timeit("test3()", setup ="from __main__ import test3") 0.214574098587 >>> def test4(): ... if 1: ... return True ... else: ... return False >>> print timeit("test4()", setup ="from __main__ import test4") 0.160849094391 |
我对这些事情感到困惑:
注意:我运行
这个问题不涉及如何进行微观基准测试(我在这个例子中做过,但我也理解这太基本了),但为什么检查"真"变量比常量慢。
在python 2中,
它们必须在运行时解析。这在python 3中已经改变了
在python 3上进行相同的测试:
1 2 3 4 5 6 7 8 | >>> timeit.timeit('test1()',setup="from __main__ import test1", number=10000000) 2.806439919999889 >>> timeit.timeit('test2()',setup="from __main__ import test2", number=10000000) 2.801301520000038 >>> timeit.timeit('test3()',setup="from __main__ import test3", number=10000000) 2.7952816800000164 >>> timeit.timeit('test4()',setup="from __main__ import test4", number=10000000) 2.7862537199999906 |
时间误差为1%,可以接受。
字节码的反汇编有明显的区别。
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> dis.dis(test1) 2 0 LOAD_GLOBAL 0 (True) 3 JUMP_IF_FALSE 5 (to 11) 6 POP_TOP 3 7 LOAD_CONST 1 (1) 10 RETURN_VALUE >> 11 POP_TOP 5 12 LOAD_CONST 2 (0) 15 RETURN_VALUE 16 LOAD_CONST 0 (None) 19 RETURN_VALUE |
正如Kabie提到的,
1 2 3 | >>> dis.dis(test2) 3 0 LOAD_CONST 1 (1) 3 RETURN_VALUE |
python编译器能够将
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> dis.dis(test3) 2 0 LOAD_GLOBAL 0 (True) 3 JUMP_IF_FALSE 5 (to 11) 6 POP_TOP 3 7 LOAD_GLOBAL 0 (True) 10 RETURN_VALUE >> 11 POP_TOP 5 12 LOAD_GLOBAL 1 (False) 15 RETURN_VALUE 16 LOAD_CONST 0 (None) 19 RETURN_VALUE |
与
1 2 3 | >>> dis.dis(test4) 3 0 LOAD_GLOBAL 0 (True) 3 RETURN_VALUE |
见