I always thought comparisons were the fastest operation a computer could execute. I remember hearing it on a presentation from D. Knuth where he'd write loops in descending order "because comparison against 0 is fast". I also read that multiplications should be slower than additions here.
I'm surprised to see that, in both Python 2 and 3, testing under both Linux and Mac, comparisons seem to be much slower than arithmetic operations.
Could anyone explain why?
%timeit 2 > 0 10000000 loops, best of 3: 41.5 ns per loop %timeit 2 * 2 10000000 loops, best of 3: 27 ns per loop %timeit 2 * 0 10000000 loops, best of 3: 27.7 ns per loop %timeit True != False 10000000 loops, best of 3: 75 ns per loop %timeit True and False 10000000 loops, best of 3: 58.8 ns per loop
And under python 3:
$ ipython3 Python 3.5.2 | packaged by conda-forge | (default, Sep 8 2016, 14:36:38) Type "copyright", "credits" or "license" for more information. IPython 5.1.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: %timeit 2 + 2 10000000 loops, best of 3: 22.9 ns per loop In [2]: %timeit 2 * 2 10000000 loops, best of 3: 23.7 ns per loop In [3]: %timeit 2 > 2 10000000 loops, best of 3: 45.5 ns per loop In [4]: %timeit True and False 10000000 loops, best of 3: 62.8 ns per loop In [5]: %timeit True != False 10000000 loops, best of 3: 92.9 ns per loop
In real arithmetic, multiplication may be faster for the following reason: When two real numbers are multiplied, the mantissae are multiplied together and the exponents are added, and these operations can be carried out in parallel.
When we're doing arithmetic, addition is easier than multiplication, so we change multiplication problems into addition problems using logarithms.
For example, in mathematics and most computer languages, multiplication is granted a higher precedence than addition, and it has been this way since the introduction of modern algebraic notation.
Multiplication is repeated addition (N=n·u=u+u+u+..., unit is preserved) , but there is another thing called product. (u×u=u2, unit is changed).
This is happening due to Constant Folding in the Peep Hole optimizer within Python compiler.
Using the dis module, if we break each of the statements to look inside how they are being translated at machine level, you will observe that all operators like inequality, equality etc are first loaded into memory and then evaluated. However, all expressions like multiplication, addition etc are calculated and loaded as a constant into memory.
Overall, this leads to a lesser number of execution steps, making the steps faster:
>>> import dis >>> def m1(): True != False >>> dis.dis(m1) 1 0 LOAD_GLOBAL 0 (True) 3 LOAD_GLOBAL 1 (False) 6 COMPARE_OP 3 (!=) 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE >>> def m2(): 2 *2 >>> dis.dis(m2) 1 0 LOAD_CONST 2 (4) 3 POP_TOP 4 LOAD_CONST 0 (None) 7 RETURN_VALUE >>> def m3(): 2*5 >>> dis.dis(m3) 1 0 LOAD_CONST 3 (10) 3 POP_TOP 4 LOAD_CONST 0 (None) 7 RETURN_VALUE >>> def m4(): 2 > 0 >>> dis.dis(m4) 1 0 LOAD_CONST 1 (2) 3 LOAD_CONST 2 (0) 6 COMPARE_OP 4 (>) 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE >>> def m5(): True and False >>> dis.dis(m5) 1 0 LOAD_GLOBAL 0 (True) 3 JUMP_IF_FALSE_OR_POP 9 6 LOAD_GLOBAL 1 (False) >> 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE
As others have explained, this is because Python's peephole optimiser optimises arithmetic operations but not comparisons.
Having written my own peephole optimiser for a Basic compiler, I can assure you that optimising constant comparisons is just as easy as optimising constant arithmetic operations. So there is no technical reason why Python should do the latter but not the former.
However, each such optimisation has to be separately programmed, and comes with two costs: the time to program it, and the extra optimising code taking up space in the Python executable. So you find yourself having to do some triage: which of these optimisations is common enough to make it worth the costs?
It seems that the Python implementers, reasonably enough, decided to optimise the arithmetic operations first. Perhaps they will get round to comparisons in a future release.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With