From fc3ccf234dc0c0bcfa0ae2b4ee1988f221c16fa3 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 13 Dec 2023 13:48:36 +0100 Subject: [PATCH] Speedup log2 code (#7106) * Speedup log2 code * Update changelog --- CHANGELOG.md | 2 ++ osmomath/decimal.go | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a946ed88b34..c7e71f1d854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,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 a3f43904288..99591a51727 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 @@ -1037,9 +1042,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)) } @@ -1049,18 +1054,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 @@ -1069,10 +1074,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) }