129 lines
2.7 KiB
Go
129 lines
2.7 KiB
Go
package branch
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"cosmossdk.io/core/store"
|
|
coretesting "cosmossdk.io/core/testing"
|
|
)
|
|
|
|
var (
|
|
stackSizes = []int{1, 10, 100}
|
|
elemsInStack = 10
|
|
)
|
|
|
|
func Benchmark_CacheStack_Set(b *testing.B) {
|
|
for _, stackSize := range stackSizes {
|
|
b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) {
|
|
bs := makeBranchStack(b, stackSize)
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
err := bs.Set([]byte{0}, []byte{0})
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
var sink any
|
|
|
|
func Benchmark_Get(b *testing.B) {
|
|
for _, stackSize := range stackSizes {
|
|
b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) {
|
|
bs := makeBranchStack(b, stackSize)
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
sink, _ = bs.Get([]byte{0})
|
|
}
|
|
})
|
|
}
|
|
if sink == nil {
|
|
b.Fatal("benchmark did not run")
|
|
}
|
|
sink = nil
|
|
}
|
|
|
|
func Benchmark_GetSparse(b *testing.B) {
|
|
var sink any
|
|
for _, stackSize := range stackSizes {
|
|
b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) {
|
|
bs := makeBranchStack(b, stackSize)
|
|
keys := func() [][]byte {
|
|
var keys [][]byte
|
|
for i := 0; i < b.N; i++ {
|
|
keys = append(keys, numToBytes(i))
|
|
}
|
|
return keys
|
|
}()
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for _, key := range keys {
|
|
sink, _ = bs.Get(key)
|
|
}
|
|
})
|
|
}
|
|
if sink == nil {
|
|
b.Fatal("benchmark did not run")
|
|
}
|
|
sink = nil
|
|
}
|
|
|
|
var (
|
|
keySink any
|
|
valueSink any
|
|
)
|
|
|
|
func Benchmark_Iterate(b *testing.B) {
|
|
for _, stackSize := range stackSizes {
|
|
b.Run(fmt.Sprintf("StackSize%d", stackSize), func(b *testing.B) {
|
|
bs := makeBranchStack(b, stackSize)
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
iter, _ := bs.Iterator(nil, nil)
|
|
for iter.Valid() {
|
|
keySink = iter.Key()
|
|
valueSink = iter.Value()
|
|
iter.Next()
|
|
}
|
|
_ = iter.Close()
|
|
}
|
|
})
|
|
}
|
|
if valueSink == nil || keySink == nil {
|
|
b.Fatal("benchmark did not run")
|
|
}
|
|
valueSink = nil
|
|
keySink = nil
|
|
}
|
|
|
|
// makeBranchStack creates a branch stack of the given size and initializes it with unique key-value pairs.
|
|
func makeBranchStack(b *testing.B, stackSize int) Store[store.KVStore] {
|
|
b.Helper()
|
|
parent := coretesting.NewMemKV()
|
|
branch := NewStore[store.KVStore](parent)
|
|
for i := 1; i < stackSize; i++ {
|
|
branch = NewStore[store.KVStore](branch)
|
|
for j := 0; j < elemsInStack; j++ {
|
|
// create unique keys by including the branch index.
|
|
key := append(numToBytes(i), numToBytes(j)...)
|
|
value := []byte{byte(j)}
|
|
err := branch.Set(key, value)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
return branch
|
|
}
|
|
|
|
func numToBytes[T ~int](n T) []byte {
|
|
return binary.BigEndian.AppendUint64(nil, uint64(n))
|
|
}
|