From 8c054fc28981d909955872869619b3a85cba2343 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 21:10:49 -0700 Subject: [PATCH] Speedup log2 code (#7106) (#7111) * Speedup log2 code * Update changelog (cherry picked from commit fc3ccf234dc0c0bcfa0ae2b4ee1988f221c16fa3) Co-authored-by: Dev Ojha --- CHANGELOG.md | 2 ++ osmomath/decimal.go | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe7d2fa1318..6a7365e087d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#6884](https://github.com/osmosis-labs/osmosis/pull/6914) Update ListPoolsByDenom function by using pool.GetPoolDenoms to filter denom directly * [#6959](https://github.com/osmosis-labs/osmosis/pull/6959) Increase high gas threshold to 2m from 1m * [#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) + ### API Breaks diff --git a/osmomath/decimal.go b/osmomath/decimal.go index b695c8dba98..714c1a23bf2 100644 --- a/osmomath/decimal.go +++ b/osmomath/decimal.go @@ -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 @@ -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)) } @@ -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 @@ -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) }