Which is the efficient way to convert a float into an int in python?
int, performance, python
Solution
Test it with `timeit`:
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.234 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.218 usec per loop
So floor division is only a faster by a small margin. Note that these values are very close, and I had to crank up the loop repeat count to iron out random influences on my machine. Even with such a high count, you need to repeat the experiments a few times to see how much the numbers still vary and what comes out faster most of the time.
This is logical, as `int()` requires a global lookup and a function call (so state is pushed and popped):
>>> import dis
>>> def use_int(n):
... return int(n)
...
>>> def use_floordiv(n):
... return n // 1
...
>>> dis.dis(use_int)
2 0 LOAD_GLOBAL 0 (int)
3 LOAD_FAST 0 (n)
6 CALL_FUNCTION 1
9 RETURN_VALUE
>>> dis.dis(use_floordiv)
2 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (1)
6 BINARY_FLOOR_DIVIDE
7 RETURN_VALUE
It is the `LOAD_GLOBAL` and `CALL_FUNCTION` opcodes that are slower than the `LOAD_CONST` and `BINARY_FLOOR_DIVIDE` opcodes; `LOAD_CONST` is a simple array lookup, `LOAD_GLOBAL` needs to do a dictionary lookup instead.
Binding `int()` to a local name can make a small difference, giving it the edge again (as it has to do less work than `// 1` floor division):
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.233 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345; int_=int' 'int_(n)'
10000000 loops, best of 3: 0.195 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.225 usec per loop
Again, you need to run this with 10 million loops to see the differences consistently.
That said, `int(n)` is a lot more explicit and unless you are doing this in a time-critical loop, `int(n)` wins it in readability over `n // 1`. The timing differences are too small to make the cognitive cost of having to work out what `// 1` does here worthwhile.
Problem
I've been using `n = int(n)` to convert a `float` into an `int`. Recently, I came across another way to do the same thing : `n = n // 1` Which is the most efficient way, and why?