我试图找出在评估条件语句(python 2.6.6)时否定布尔值是否有任何惩罚。我首先尝试了这个简单的测试(没有else
分支)
>>> import timeit
>>> timeit.timeit("if not True: pass", number=100000)
0.011913061141967773
>>> timeit.timeit("if True: pass", number=100000)
0.018882036209106445
所以我认为结果是有偏差的,因为 pass 语句可能会被转换为 noop ,这至少是一些操作。
我做了第二次尝试,得到了这些结果:
>>> timeit.timeit("a=False\nif not a: pass\nelse: pass", number=100000)
0.02387714385986328
>>> timeit.timeit("a=False\nif a: pass\nelse: pass", number=100000)
0.015386819839477539
>>> timeit.timeit("a=True\nif a: pass\nelse: pass", number=100000)
0.02389812469482422
>>> timeit.timeit("a=True\nif not a: pass\nelse: pass", number=100000)
0.015424966812133789
我没想到会看到任何大的惩罚,但从这个结果来看,评估else
分支似乎比隐式then
分支便宜。而且差别很大!
所以第三次尝试返回这些结果:
>>> timeit.timeit("if True: a=1\nelse: a=1", number=100000)
0.022008895874023438
>>> timeit.timeit("if not True: a=1\nelse: a=1", number=100000)
0.022121906280517578
最后我得到了预期的结果。虽然出于好奇,我最后一次尝试:
>>> timeit.timeit("if False: a=1\nelse: a=1", number=100000)
0.02385997772216797
>>> timeit.timeit("if not False: a=1\nelse: a=1", number=100000)
0.02244400978088379
就是这样......我不知道为什么导致then
分支的否定条件更快。
可能会发生什么?
所有这些结果都可以在我的计算机上重现,无论我运行它们多少次,我都会得到几乎相同的结果。
我认为第一个测试存在偏差,因为编译器可能已经else: pass
完全删除了该部分。那可能吗?
可能所有这些结果都与 CPU 中的分支预测器有关吗?
还有其他可能的罪魁祸首吗?