Completed clean root directory structure: - Root now contains only: .git, .env, docs/, orig/ - Moved all remaining files and directories to orig/: - Config files (.claude, .dockerignore, .drone.yml, etc.) - All .env variants (except active .env) - Git config (.gitconfig, .github, .gitignore, etc.) - Tool configs (.golangci.yml, .revive.toml, etc.) - Documentation (*.md files, @prompts) - Build files (Dockerfiles, Makefile, go.mod, go.sum) - Docker compose files - All source directories (scripts, tests, tools, etc.) - Runtime directories (logs, monitoring, reports) - Dependency files (node_modules, lib, cache) - Special files (--delete) - Removed empty runtime directories (bin/, data/) V2 structure is now clean: - docs/planning/ - V2 planning documents - orig/ - Complete V1 codebase preserved - .env - Active environment config (not in git) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
159 lines
4.1 KiB
Go
159 lines
4.1 KiB
Go
package benchmarks
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/fraktal/mev-beta/pkg/uniswap"
|
|
)
|
|
|
|
// BenchmarkSqrtPriceX96ToPrice benchmarks the SqrtPriceX96ToPrice function
|
|
func BenchmarkSqrtPriceX96ToPrice(b *testing.B) {
|
|
sqrtPriceX96 := new(big.Int)
|
|
sqrtPriceX96.SetString("79228162514264337593543950336", 10) // 2^96
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = uniswap.SqrtPriceX96ToPrice(sqrtPriceX96)
|
|
}
|
|
}
|
|
|
|
// BenchmarkPriceToSqrtPriceX96 benchmarks the PriceToSqrtPriceX96 function
|
|
func BenchmarkPriceToSqrtPriceX96(b *testing.B) {
|
|
price := new(big.Float).SetFloat64(1.0)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = uniswap.PriceToSqrtPriceX96(price)
|
|
}
|
|
}
|
|
|
|
// BenchmarkTickToSqrtPriceX96 benchmarks the TickToSqrtPriceX96 function
|
|
func BenchmarkTickToSqrtPriceX96(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = uniswap.TickToSqrtPriceX96(0)
|
|
}
|
|
}
|
|
|
|
// BenchmarkSqrtPriceX96ToTick benchmarks the SqrtPriceX96ToTick function
|
|
func BenchmarkSqrtPriceX96ToTick(b *testing.B) {
|
|
sqrtPriceX96 := new(big.Int)
|
|
sqrtPriceX96.SetString("79228162514264337593543950336", 10) // 2^96
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = uniswap.SqrtPriceX96ToTick(sqrtPriceX96)
|
|
}
|
|
}
|
|
|
|
// BenchmarkPricingConversionsSequential benchmarks sequential pricing conversions
|
|
func BenchmarkPricingConversionsSequential(b *testing.B) {
|
|
price := new(big.Float).SetFloat64(1.0)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
sqrtPriceX96 := uniswap.PriceToSqrtPriceX96(price)
|
|
tick := uniswap.SqrtPriceX96ToTick(sqrtPriceX96)
|
|
backToSqrt := uniswap.TickToSqrtPriceX96(tick)
|
|
_ = uniswap.SqrtPriceX96ToPrice(backToSqrt)
|
|
}
|
|
}
|
|
|
|
// BenchmarkPricingCalculationRealistic benchmarks realistic pricing calculations
|
|
func BenchmarkPricingCalculationRealistic(b *testing.B) {
|
|
testCases := []struct {
|
|
name string
|
|
sqrtPriceX96 string
|
|
}{
|
|
{"ETH_USDC_1800", "2231455953840924584200896000"}, // ~1800 USDC per ETH
|
|
{"ETH_USDC_3000", "2890903041336652768307200000"}, // ~3000 USDC per ETH
|
|
{"WBTC_ETH_15", "977228162514264337593543950"}, // ~15 ETH per WBTC
|
|
{"DAI_USDC_1", "79228162514264337593543950336"}, // ~1 DAI per USDC
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
b.Run(tc.name, func(b *testing.B) {
|
|
sqrtPriceX96 := new(big.Int)
|
|
sqrtPriceX96.SetString(tc.sqrtPriceX96, 10)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
price := uniswap.SqrtPriceX96ToPrice(sqrtPriceX96)
|
|
tick := uniswap.SqrtPriceX96ToTick(sqrtPriceX96)
|
|
backToSqrt := uniswap.TickToSqrtPriceX96(tick)
|
|
_ = uniswap.SqrtPriceX96ToPrice(backToSqrt)
|
|
|
|
// Verify we get similar price back (within reasonable precision)
|
|
require.NotNil(b, price)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// BenchmarkExtremePriceValues benchmarks extreme price value conversions
|
|
func BenchmarkExtremePriceValues(b *testing.B) {
|
|
extremeCases := []struct {
|
|
name string
|
|
price float64
|
|
}{
|
|
{"VeryLow_0.000001", 0.000001},
|
|
{"Low_0.01", 0.01},
|
|
{"Normal_1.0", 1.0},
|
|
{"High_100.0", 100.0},
|
|
{"VeryHigh_1000000.0", 1000000.0},
|
|
}
|
|
|
|
for _, tc := range extremeCases {
|
|
b.Run(tc.name, func(b *testing.B) {
|
|
price := new(big.Float).SetFloat64(tc.price)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
sqrtPriceX96 := uniswap.PriceToSqrtPriceX96(price)
|
|
tick := uniswap.SqrtPriceX96ToTick(sqrtPriceX96)
|
|
backToSqrt := uniswap.TickToSqrtPriceX96(tick)
|
|
_ = uniswap.SqrtPriceX96ToPrice(backToSqrt)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntOperations benchmarks the underlying big.Int operations
|
|
func BenchmarkBigIntOperations(b *testing.B) {
|
|
b.Run("BigInt_Multiplication", func(b *testing.B) {
|
|
x := big.NewInt(1000000)
|
|
y := big.NewInt(2000000)
|
|
result := new(big.Int)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result.Mul(x, y)
|
|
}
|
|
})
|
|
|
|
b.Run("BigInt_Division", func(b *testing.B) {
|
|
x := big.NewInt(1000000000000)
|
|
y := big.NewInt(1000000)
|
|
result := new(big.Int)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result.Div(x, y)
|
|
}
|
|
})
|
|
|
|
b.Run("BigFloat_Operations", func(b *testing.B) {
|
|
x := big.NewFloat(1000000.5)
|
|
y := big.NewFloat(2000000.3)
|
|
result := new(big.Float)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result.Mul(x, y)
|
|
}
|
|
})
|
|
}
|