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?

Original source