github.com/cosmos/cosmos-sdk@v0.50.10/types/coin_benchmark_test.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "testing" 6 7 "cosmossdk.io/math" 8 ) 9 10 func coinName(suffix int) string { 11 return fmt.Sprintf("coinz%04d", suffix) 12 } 13 14 func BenchmarkCoinsAdditionIntersect(b *testing.B) { 15 b.ReportAllocs() 16 benchmarkingFunc := func(numCoinsA, numCoinsB int) func(b *testing.B) { 17 return func(b *testing.B) { 18 b.ReportAllocs() 19 coinsA := Coins(make([]Coin, numCoinsA)) 20 coinsB := Coins(make([]Coin, numCoinsB)) 21 22 for i := 0; i < numCoinsA; i++ { 23 coinsA[i] = NewCoin(coinName(i), math.NewInt(int64(i))) 24 } 25 for i := 0; i < numCoinsB; i++ { 26 coinsB[i] = NewCoin(coinName(i), math.NewInt(int64(i))) 27 } 28 29 b.ResetTimer() 30 31 for i := 0; i < b.N; i++ { 32 coinsA.Add(coinsB...) 33 } 34 } 35 } 36 37 benchmarkSizes := [][]int{{1, 1}, {5, 5}, {5, 20}, {1, 1000}, {2, 1000}} 38 for i := 0; i < len(benchmarkSizes); i++ { 39 sizeA := benchmarkSizes[i][0] 40 sizeB := benchmarkSizes[i][1] 41 b.Run(fmt.Sprintf("sizes: A_%d, B_%d", sizeA, sizeB), benchmarkingFunc(sizeA, sizeB)) 42 } 43 } 44 45 func BenchmarkCoinsAdditionNoIntersect(b *testing.B) { 46 b.ReportAllocs() 47 benchmarkingFunc := func(numCoinsA, numCoinsB int) func(b *testing.B) { 48 return func(b *testing.B) { 49 b.ReportAllocs() 50 coinsA := Coins(make([]Coin, numCoinsA)) 51 coinsB := Coins(make([]Coin, numCoinsB)) 52 53 for i := 0; i < numCoinsA; i++ { 54 coinsA[i] = NewCoin(coinName(numCoinsB+i), math.NewInt(int64(i))) 55 } 56 for i := 0; i < numCoinsB; i++ { 57 coinsB[i] = NewCoin(coinName(i), math.NewInt(int64(i))) 58 } 59 60 b.ResetTimer() 61 62 for i := 0; i < b.N; i++ { 63 coinsA.Add(coinsB...) 64 } 65 } 66 } 67 68 benchmarkSizes := [][]int{{1, 1}, {5, 5}, {5, 20}, {1, 1000}, {2, 1000}, {1000, 2}} 69 for i := 0; i < len(benchmarkSizes); i++ { 70 sizeA := benchmarkSizes[i][0] 71 sizeB := benchmarkSizes[i][1] 72 b.Run(fmt.Sprintf("sizes: A_%d, B_%d", sizeA, sizeB), benchmarkingFunc(sizeA, sizeB)) 73 } 74 } 75 76 func BenchmarkSumOfCoinAdds(b *testing.B) { 77 // This benchmark tests the performance of adding a large number of coins 78 // into a single coin set. 79 // it does numAdds additions, each addition has (numIntersectingCoins) that contain denoms 80 // already in the sum, and (coinsPerAdd - numIntersectingCoins) that are new denoms. 81 benchmarkingFunc := func(numAdds, coinsPerAdd, numIntersectingCoins int, sumFn func([]Coins) Coins) func(b *testing.B) { 82 return func(b *testing.B) { 83 b.ReportAllocs() 84 addCoins := make([]Coins, numAdds) 85 nonIntersectingCoins := coinsPerAdd - numIntersectingCoins 86 87 for i := 0; i < numAdds; i++ { 88 intersectCoins := make([]Coin, numIntersectingCoins) 89 num := math.NewInt(int64(i)) 90 for j := 0; j < numIntersectingCoins; j++ { 91 intersectCoins[j] = NewCoin(coinName(j+1_000_000_000), num) 92 } 93 addCoins[i] = intersectCoins 94 for j := 0; j < nonIntersectingCoins; j++ { 95 addCoins[i] = addCoins[i].Add(NewCoin(coinName(i*nonIntersectingCoins+j), num)) 96 } 97 } 98 99 b.ResetTimer() 100 101 for i := 0; i < b.N; i++ { 102 sumFn(addCoins) 103 } 104 } 105 } 106 107 MapCoinsSumFn := func(coins []Coins) Coins { 108 sum := MapCoins{} 109 for _, coin := range coins { 110 sum.Add(coin...) 111 } 112 return sum.ToCoins() 113 } 114 CoinsSumFn := func(coins []Coins) Coins { 115 sum := Coins{} 116 for _, coin := range coins { 117 sum = sum.Add(coin...) 118 } 119 return sum 120 } 121 122 // larger benchmarks with non-overlapping coins won't terminate in reasonable timeframes with sdk.Coins 123 // they work fine with MapCoins 124 benchmarkSizes := [][]int{{5, 2, 1000}, {10, 10, 10000}} 125 sumFns := []struct { 126 name string 127 fn func([]Coins) Coins 128 }{ 129 {"MapCoins", MapCoinsSumFn}, {"Coins", CoinsSumFn}, 130 } 131 for i := 0; i < len(benchmarkSizes); i++ { 132 for j := 0; j < 2; j++ { 133 coinsPerAdd := benchmarkSizes[i][0] 134 intersectingCoinsPerAdd := benchmarkSizes[i][1] 135 numAdds := benchmarkSizes[i][2] 136 sumFn := sumFns[j] 137 b.Run(fmt.Sprintf("Fn: %s, num adds: %d, coinsPerAdd: %d, intersecting: %d", 138 sumFn.name, numAdds, coinsPerAdd, intersectingCoinsPerAdd), 139 benchmarkingFunc(numAdds, coinsPerAdd, intersectingCoinsPerAdd, sumFn.fn)) 140 } 141 } 142 }