为什么 a / (b*c) 在 Python 中(以及一般情况下)比 a / b / c 慢?

Tho*_*mas 0 python math performance cpu-speed

在为神经网络库编写一些数学导数函数时,我偶然发现了一个有趣的优化问题。事实证明,与大值a / (b*c)相比a / b / c,表达式需要更长的时间来计算(见timeit下文)。但由于这两个表达式是相等的:

  • Python 不应该在低端以相同的方式进行优化吗?
  • 是有一个情况a / (b*c),因为它似乎是慢?
  • 或者我错过了什么,而两者并不总是平等的?

提前致谢 :)

In [2]: timeit.timeit('1293579283509136012369019234623462346423623462346342635610 / (52346234623632464236234624362436234612830128521357*32189512234623462637501237)')
Out[2]: 0.2646541080002862

In [3]: timeit.timeit('1293579283509136012369019234623462346423623462346342635610 / 52346234623632464236234624362436234612830128521357 / 32189512234623462637501237')
Out[3]: 0.008390166000026511
Run Code Online (Sandbox Code Playgroud)

khe*_*ood 5

为什么比较a/(b*c)慢?

(b*c)以无限的精度乘以两个非常大的整数。这是比执行浮点除法(精度有限)更昂贵的操作。

这两个计算是等价的吗?

在实践中,a/(b*c)a/b/c会产生不同的结果,因为浮点计算有不准确之处,并以不同的顺序做的操作可以产生不同的结果。

例如:

a = 10 ** 33
b = 10000000000000002
c = 10 ** 17
print(a / b / c)    # 0.9999999999999999
print(a / (b * c))  # 0.9999999999999998
Run Code Online (Sandbox Code Playgroud)

它归结为计算机如何处理它使用的数字。

为什么 Python 不计算a/(b*c)a/b/c

那会产生出人意料的结果。用户应该能够期望

d = b*c
a / d
Run Code Online (Sandbox Code Playgroud)

应该有相同的结果

a / (b*c)
Run Code Online (Sandbox Code Playgroud)

因此,如果a / (b*c)给出不同的结果,它将成为非常神秘行为的来源,因为它被神奇地替换为a / b / c.