我正在做以下事情:
TOLERANCE = 13
some_float = ...
round(some_float, TOLERANCE)
Run Code Online (Sandbox Code Playgroud)
这是多次运行,因此性能很重要.由于浮点表示错误,我必须舍入some_float.我实际上并不需要在这个意义上"舍入"数字,只需删除13个尾随数字后的数字.
有更快的方法吗?
我做了一些长凳比较round(some_float, TOLERANCE)
有int(some_float * p + 0.5)/p
(其中p为10**TOLERANCE)
和这里的结果:
我的板凳:
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)
Run Code Online (Sandbox Code Playgroud)
结果:
12.24399 6.208600997924805
12.24399 3.525486946105957
Run Code Online (Sandbox Code Playgroud)
所以int
解决方案更快.round
可能更好地处理负数的舍入(如有人评论,它会进行大量额外调用,因此代码更复杂).根据输入数字的符号,舍入可能不同.准确性与原始速度再次相同.
是否添加0.5
圆形或截断.这似乎是一个细节,但int
解决方案(提供10**TOLERANCE
预先计算)似乎更快.
如果你想使用这种技术,你可能会想把舍入代码放在一个函数中:
TOLERANCE = 5
p = float(10**TOLERANCE)
def my_round_5(some_float):
return int(some_float * p + 0.5)/p
Run Code Online (Sandbox Code Playgroud)
并称之为:
r2 = my_round(some_float)
Run Code Online (Sandbox Code Playgroud)
这仍然会round
比使用公式内联更慢(因为函数调用不是免费的)
使用int
、乘法和除法更快。您可以timeit
使用ipython
来快速对 Python 代码进行基准测试。
In [7]: %timeit int(1.12345678901234*(10**13))/(10.**13)\n1000000 loops, best of 3: 380 ns per loop\n\nIn [8]: %timeit round(1.12345678901234, 13)\n1000000 loops, best of 3: 1.32 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n