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?
Python has three ways to turn a floating-point value into a whole (integer) number: The built-in round() function rounds values up and down. The math. floor() function rounds down to the next full integer.
To convert, or cast, a string to an integer in Python, you use the int() built-in function. The function takes in as a parameter the initial string you want to convert, and returns the integer equivalent of the value you passed.
By using the float() function, we can convert integers to floats.
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.
Although Martijn Pieters answered your question of what is faster and how to test it I feel like speed isn't that important for such a small operation. I would use int() for readability as Inbar Rose said. Typically when dealing with something this small readability is far more important; although, a common equation can be an exception to this.
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