Python round () too slow, faster way to lower precision?
I am doing the following:
TOLERANCE = 13 some_float = ... round(some_float, TOLERANCE)
This is done many times, so performance is important. I need to round some_float due to floating point view error. I don't really need to "round" the number in that sense, just remove the digits after the 13 lagging digits.
Is there a faster way to do this?
source to share
I made some stands to compare round(some_float, TOLERANCE)
with int(some_float * p + 0.5)/p
(with p as 10**TOLERANCE)
and here are the results:
- round: 6.20 seconds
- Int divide + multiply: 3.53
my bench:
import time TOLERANCE = 5 some_float = 12.2439924563634564564564 nb_loops = 10000000 start_time = time.time() for _ in range(nb_loops): r1 = round(some_float, TOLERANCE) print(r1,time.time()-start_time) start_time = time.time() p = float(10**TOLERANCE) for _ in range(nb_loops): r2 = int(some_float * p + 0.5)/p print(r2,time.time()-start_time)
result:
12.24399 6.208600997924805
12.24399 3.525486946105957
so the solution is int
faster. round
probably does a better job of rounding negative numbers (as someone commented, it makes a lot of extra calls, so the code is more complicated). The rounding can be different depending on the sign of the entered number. Accuracy versus raw speed, again.
Add 0.5
or not round or truncate. This seems to be a detail for you, but the solution int
(assuming it is 10**TOLERANCE
precomputed) seems to be faster.
If you want to use this technique, you might want to put the rounding code in a function:
TOLERANCE = 5 p = float(10**TOLERANCE) def my_round_5(some_float): return int(some_float * p + 0.5)/p
and call it like this:
r2 = my_round(some_float)
it will still be faster than round
, but slightly slower than using the inline formula (because the function call is not free)
note that i used p = float(10**TOLERANCE)
, not p = 10**TOLERANCE
, so the code is python 2 compatible (otherwise it truncates the decimal part due to integer division)
source to share
Using int
, multiply and divide faster. You can use timeit
with ipython
to quickly evaluate Python code.
In [7]: %timeit int(1.12345678901234*(10**13))/(10.**13)
1000000 loops, best of 3: 380 ns per loop
In [8]: %timeit round(1.12345678901234, 13)
1000000 loops, best of 3: 1.32 µs per loop
source to share