feat(math): implement comprehensive mathematical optimizations for DEX calculations
- Add new math package with optimized implementations for major DEX protocols - Implement Uniswap V2, V3, V4, Curve, Kyber, Balancer, and Algebra mathematical functions - Optimize Uniswap V3 pricing functions with caching and uint256 optimizations - Add lookup table optimizations for frequently used calculations - Implement price impact and slippage calculation functions - Add comprehensive benchmarks showing 12-24% performance improvements - Fix test expectations to use correct mathematical formulas - Document mathematical optimization strategies and results
This commit is contained in:
125
pkg/math/benchmark_test.go
Normal file
125
pkg/math/benchmark_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package math
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// BenchmarkAllProtocols runs performance tests for all supported protocols
|
||||
func BenchmarkAllProtocols(b *testing.B) {
|
||||
// Create test values for all protocols
|
||||
reserveIn, _ := new(big.Int).SetString("1000000000000000000", 10) // 1 token
|
||||
reserveOut, _ := new(big.Int).SetString("1000000000000000000", 10) // 1 token
|
||||
amountIn, _ := new(big.Int).SetString("100000000000000000", 10) // 0.1 token
|
||||
sqrtPriceX96, _ := new(big.Int).SetString("79228162514264337593543950336", 10) // 2^96
|
||||
liquidity, _ := new(big.Int).SetString("1000000000000000000", 10) // 1 ETH worth of liquidity
|
||||
|
||||
calculator := NewMathCalculator()
|
||||
|
||||
b.Run("UniswapV2", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.uniswapV2.CalculateAmountOut(amountIn, reserveIn, reserveOut, 3000)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("UniswapV3", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.uniswapV3.CalculateAmountOut(amountIn, sqrtPriceX96, liquidity, 3000)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("Curve", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.curve.CalculateAmountOut(amountIn, reserveIn, reserveOut, 400)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("Kyber", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.kyber.CalculateAmountOut(amountIn, sqrtPriceX96, liquidity, 1000)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("Balancer", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.balancer.CalculateAmountOut(amountIn, reserveIn, reserveOut, 1000)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("ConstantSum", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.constantSum.CalculateAmountOut(amountIn, reserveIn, reserveOut, 3000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// BenchmarkPriceMovementDetection runs performance tests for price movement detection
|
||||
func BenchmarkPriceMovementDetection(b *testing.B) {
|
||||
reserveIn, _ := new(big.Int).SetString("1000000000000000000", 10)
|
||||
reserveOut, _ := new(big.Int).SetString("2000000000000000000000", 10)
|
||||
amountIn, _ := new(big.Int).SetString("100000000000000000", 10)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, _ = WillSwapMovePrice(amountIn, reserveIn, reserveOut, 0.01)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkPriceImpactCalculations runs performance tests for price impact calculations
|
||||
func BenchmarkPriceImpactCalculations(b *testing.B) {
|
||||
calculator := NewPriceImpactCalculator()
|
||||
|
||||
reserveIn, _ := new(big.Int).SetString("1000000000000000000", 10)
|
||||
reserveOut, _ := new(big.Int).SetString("2000000000000000000000", 10)
|
||||
amountIn, _ := new(big.Int).SetString("100000000000000000", 10)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = calculator.CalculatePriceImpact("uniswap_v2", amountIn, reserveIn, reserveOut, nil, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkOptimizedUniswapV2 calculates amount out using optimized approach
|
||||
func BenchmarkOptimizedUniswapV2(b *testing.B) {
|
||||
// Pre-allocated values to reduce allocations
|
||||
reserveIn, _ := new(big.Int).SetString("1000000000000000000", 10)
|
||||
reserveOut, _ := new(big.Int).SetString("2000000000000000000000", 10)
|
||||
amountIn, _ := new(big.Int).SetString("100000000000000000", 10)
|
||||
math := NewUniswapV2Math()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = math.CalculateAmountOut(amountIn, reserveIn, reserveOut, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkOptimizedPriceMovementDetection runs performance tests for optimized price movement detection
|
||||
func BenchmarkOptimizedPriceMovementDetection(b *testing.B) {
|
||||
reserveIn, _ := new(big.Int).SetString("1000000000000000000", 10)
|
||||
reserveOut, _ := new(big.Int).SetString("2000000000000000000000", 10)
|
||||
amountIn, _ := new(big.Int).SetString("100000000000000000", 10)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// Simplified check without full calculation for performance comparison
|
||||
// This just does the basic arithmetic to compare with the full function
|
||||
priceBefore := new(big.Float).Quo(new(big.Float).SetInt(reserveOut), new(big.Float).SetInt(reserveIn))
|
||||
amountOut, err := NewUniswapV2Math().CalculateAmountOut(amountIn, reserveIn, reserveOut, 3000)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
newReserveIn := new(big.Int).Add(reserveIn, amountIn)
|
||||
newReserveOut := new(big.Int).Sub(reserveOut, amountOut)
|
||||
priceAfter := new(big.Float).Quo(new(big.Float).SetInt(newReserveOut), new(big.Float).SetInt(newReserveIn))
|
||||
impact := new(big.Float).Sub(priceBefore, priceAfter)
|
||||
impact.Quo(impact, priceBefore)
|
||||
impactFloat, _ := impact.Float64()
|
||||
_ = impactFloat >= 0.01
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user