Python round()太慢,更快的方法来降低精度?

时间:2017-07-05 08:19:15

标签: python

我正在做以下事情:

TOLERANCE = 13
some_float = ...
round(some_float, TOLERANCE)

这是多次运行,所以性能很重要。由于浮点表示错误,我必须舍入some_float。我实际上并不需要" round"在这个意义上的数字,只需删除13个尾随数字后的数字。

有更快的方法吗?

2 个答案:

答案 0 :(得分:6)

我已经做了一些工作,将round(some_float, TOLERANCE)int(some_float * p + 0.5)/p进行比较(p为10**TOLERANCE),结果如下:

  • round:6.20秒
  • int divide + multiply:3.53

我的替补席:

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 = 10**TOLERANCE
for _ in range(nb_loops):
    r2 = int(some_float * p + 0.5)/p
print(r2,time.time()-start_time)

结果:

12.24399 6.208600997924805
12.24399 3.525486946105957

所以int解决方案更快。 round可能更好地处理负数的舍入(有人评论说,它会产生很多额外的调用,所以代码更复杂)。根据输入数字的符号,舍入可能不同。准确性与原始速度再次相同。

添加0.5或不加圆或截断。这似乎是一个细节,但int解决方案(假设预先计算10**TOLERANCE)似乎更快。

如果你想使用这种技术,你可能会想把舍入代码放在一个函数中:

TOLERANCE = 5
p = 10**TOLERANCE
def my_round_5(some_float):
    return int(some_float * p + 0.5)/p

并将其称为:

r2 = my_round(some_float)

仍然比round快,但比使用公式内联慢一点(因为函数调用不是免费的)

答案 1 :(得分:1)

使用int,乘法和除法更快。您可以将timeitipython一起使用,以便快速对Python代码进行基准测试。

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