条件文(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に変換される可能性があるため、結果が歪んでいると思います。
私は2回目の試行を行い、次の結果を得ました。
>>> 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
ます。そして、その違いは非常に大きいです!
したがって、3回目の試行では、次の結果が返されます。
>>> 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の分岐予測に関連している可能性がありますか?
他に考えられる原因はありますか?