Is there any benefit in performance using integer division operator over math.floor?
7 // 2
over
math.floor(7/2)
Is there any benefit in performance using integer division operator over math.floor?
7 // 2
over
math.floor(7/2)
Integer division is much faster than a math.floor function call:
>>> import timeit
>>> timeit.timeit('7//2')
0.024671780910702337
>>> timeit.timeit('floor(7/2)', setup='from math import floor')
0.27053647879827736
>>> timeit.timeit('math.floor(7/2)', setup='import math')
0.3131167508719699
As you can see with this disassembly, using the math module's floor function (with import math and math.floor or from math import floor and floor) involve extra lookups and function calls over the plain integer division:
>>> import dis
>>> import math
>>> from math import floor
>>> def integer_division():
... 7//2
...
>>> def math_floor():
... floor(7/2)
...
>>> def math_full_floor():
... math.floor(7/2)
...
>>> dis.dis(integer_division)
2 0 LOAD_CONST 3 (3)
3 POP_TOP
4 LOAD_CONST 0 (None)
7 RETURN_VALUE
>>> dis.dis(math_floor)
2 0 LOAD_GLOBAL 0 (floor)
3 LOAD_CONST 3 (3.5)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> dis.dis(math_full_floor)
2 0 LOAD_GLOBAL 0 (math)
3 LOAD_ATTR 1 (floor)
6 LOAD_CONST 3 (3.5)
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
Certainly, there's some overhead in a function call, and if you do this enough times, you see a difference in speed:
Run time for //: 12.940021991729736 sec
Run time for floor: 26.933987855911255 sec
Here's the code I ran:
from time import time
from math import floor
start_time = time()
for i in range(1, 10000):
for j in range(1, 10000):
result = i // j
print('Run time for //:', time() - start_time, 'sec')
start_time = time()
for i in range(1, 10000):
for j in range(1, 10000):
result = floor(i/j)
print('Run time for floor:', time() - start_time, 'sec')