当我处理非常小的数字时,我将操作(1)更改为(2)。
在此转换之后,时间成本是相同的,但是当我尝试使用decimal.Decimal提高精度并将(2)转换为(3)时,时间成本会爆炸(~10次) )。
是否有解决方案来减少时间并保持相同的精度?
(1)
alpha = 1. (fyt * qyt ) / (fxt * qxt)
(2)
pow(10, log10(fyt) + log10(qyt) - log10(fxt) - log10(qxt))
(3)
alpha = 10**(Decimal(fyt).log10() + Decimal(qyt).log10() - Decimal(fxt).log10() - Decimal(qxt).log10())
答案 0 :(得分:1)
有一个名为cDecimal
的外部包,它是Decimal模块的C实现。我从来没有使用它,但可能想尝试一下。
答案 1 :(得分:1)
我想说这是预料之中的,因为你在这里有10**x
类的幂计算,在十进制的情况下应该意味着在每一步之后检查精度。
考虑下面的例子,可以清楚地看到十进制功率操作非常昂贵:
In [6]: from decimal import Decimal
In [7]: %timeit 10**.0123456789
100000000 loops, best of 3: 16.6 ns per loop
In [8]: %timeit 10**Decimal(.0123456789)
10000 loops, best of 3: 95.3 µs per loop
所以,不是对(3)方程进行十进制运算,而是直接在第一个(1)上进行:
alpha = (Decimal(fyt) * Decimal(qyt)) / (Decimal(fxt) * Decimal(qxt))
这应该足够快,因为总共只有3个操作,并且应该具有相同的精度,因为我们使用的是Decimal
。