Skip to content

Commit

Permalink
Speedup log2 code (#7106)
Browse files Browse the repository at this point in the history
* Speedup log2 code

* Update changelog

(cherry picked from commit fc3ccf2)
  • Loading branch information
ValarDragon authored and mergify[bot] committed Dec 13, 2023
1 parent f7c9600 commit 8c60e12
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Misc Improvements

* [#7093](https://github.com/osmosis-labs/osmosis/pull/7093),[#7100](https://github.com/osmosis-labs/osmosis/pull/7100) Lower CPU overheads of the Osmosis epoch.
* [#7106](https://github.com/osmosis-labs/osmosis/pull/7106) Halve the time of log2 calculation (speeds up TWAP code)


## v20.5.1

Expand Down
21 changes: 13 additions & 8 deletions osmomath/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ var (

// precisionFactors are used to adjust the scale of big.Int values to match the desired precision
precisionFactors = make(map[uint64]*big.Int)

zeroBigDec BigDec = ZeroBigDec()
oneBigDec BigDec = OneBigDec()
oneHalfBigDec BigDec = oneBigDec.Quo(twoBigDec)
negOneBigDec BigDec = oneBigDec.Neg()
)

// Decimal errors
Expand Down Expand Up @@ -1028,9 +1033,9 @@ func DecApproxEq(t *testing.T, d1 BigDec, d2 BigDec, tol BigDec) (*testing.T, bo
func (x BigDec) LogBase2() BigDec {
// create a new decimal to avoid mutating
// the receiver's int buffer.
xCopy := ZeroBigDec()
xCopy := BigDec{}
xCopy.i = new(big.Int).Set(x.i)
if xCopy.LTE(ZeroBigDec()) {
if xCopy.LTE(zeroBigDec) {
panic(fmt.Sprintf("log is not defined at <= 0, given (%s)", xCopy))
}

Expand All @@ -1040,18 +1045,18 @@ func (x BigDec) LogBase2() BigDec {
y := ZeroBigDec()

// repeat until: x >= 1.
for xCopy.LT(OneBigDec()) {
for xCopy.LT(oneBigDec) {
xCopy.i.Lsh(xCopy.i, 1)
y = y.Sub(OneBigDec())
y.AddMut(negOneBigDec)
}

// repeat until: x < 2.
for xCopy.GTE(twoBigDec) {
xCopy.i.Rsh(xCopy.i, 1)
y = y.Add(OneBigDec())
y.AddMut(oneBigDec)
}

b := OneBigDec().Quo(twoBigDec)
b := oneHalfBigDec.Clone()

// N.B. At this point x is a positive real number representing
// mantissa of the log. We estimate it using the following
Expand All @@ -1060,10 +1065,10 @@ func (x BigDec) LogBase2() BigDec {
// This has shown precision of 32 digits relative
// to Wolfram Alpha in tests.
for i := 0; i < maxLog2Iterations; i++ {
xCopy = xCopy.Mul(xCopy)
xCopy.MulMut(xCopy)
if xCopy.GTE(twoBigDec) {
xCopy.i.Rsh(xCopy.i, 1)
y = y.Add(b)
y.AddMut(b)
}
b.i.Rsh(b.i, 1)
}
Expand Down

0 comments on commit 8c60e12

Please sign in to comment.