120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package cachekv_test
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"testing"
|
|
|
|
coretesting "cosmossdk.io/core/testing"
|
|
"cosmossdk.io/store/cachekv"
|
|
"cosmossdk.io/store/dbadapter"
|
|
)
|
|
|
|
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++ {
|
|
bs.Set([]byte{0}, []byte{0})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Gets the same key from the branch store.
|
|
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("prevent compiler optimization")
|
|
}
|
|
sink = nil
|
|
}
|
|
|
|
// Gets always different keys.
|
|
func Benchmark_GetSparse(b *testing.B) {
|
|
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, 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 keySink == nil || valueSink == nil {
|
|
b.Fatal("Benchmark did not run")
|
|
}
|
|
keySink = nil
|
|
valueSink = nil
|
|
}
|
|
|
|
// makeBranchStack creates a branch stack of the given size and initializes it with unique key-value pairs.
|
|
func makeBranchStack(_ *testing.B, stackSize int) *cachekv.Store {
|
|
parent := dbadapter.Store{DB: coretesting.NewMemDB()}
|
|
branch := cachekv.NewStore(parent)
|
|
for i := 1; i < stackSize; i++ {
|
|
branch = cachekv.NewStore(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)}
|
|
branch.Set(key, value)
|
|
}
|
|
}
|
|
return branch
|
|
}
|
|
|
|
func numToBytes[T ~int](n T) []byte {
|
|
return binary.BigEndian.AppendUint64(nil, uint64(n))
|
|
}
|