feat(serverv2): add benchmarks of (old) cacheKV vs branch (#22497)
This commit is contained in:
parent
9d6d1067bc
commit
3ebd7e53ed
@ -1,6 +1,7 @@
|
||||
package branch
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@ -20,12 +21,17 @@ func Benchmark_CacheStack_Set(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = bs.Set([]byte{0}, []byte{0})
|
||||
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) {
|
||||
@ -33,15 +39,47 @@ func Benchmark_Get(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = bs.Get([]byte{0})
|
||||
sink, _ = bs.Get([]byte{0})
|
||||
}
|
||||
})
|
||||
}
|
||||
if sink == nil {
|
||||
b.Fatal("benchmark did not run")
|
||||
}
|
||||
sink = nil
|
||||
}
|
||||
|
||||
func Benchmark_Iterate(b *testing.B) {
|
||||
var keySink, valueSink any
|
||||
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)
|
||||
@ -58,9 +96,11 @@ func Benchmark_Iterate(b *testing.B) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_ = keySink
|
||||
_ = valueSink
|
||||
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.
|
||||
@ -71,7 +111,7 @@ func makeBranchStack(b *testing.B, stackSize int) Store[store.KVStore] {
|
||||
branch = NewStore[store.KVStore](branch)
|
||||
for j := 0; j < elemsInStack; j++ {
|
||||
// create unique keys by including the branch index.
|
||||
key := []byte{byte(i), byte(j)}
|
||||
key := append(numToBytes(i), numToBytes(j)...)
|
||||
value := []byte{byte(j)}
|
||||
err := branch.Set(key, value)
|
||||
if err != nil {
|
||||
@ -81,3 +121,7 @@ func makeBranchStack(b *testing.B, stackSize int) Store[store.KVStore] {
|
||||
}
|
||||
return branch
|
||||
}
|
||||
|
||||
func numToBytes[T ~int](n T) []byte {
|
||||
return binary.BigEndian.AppendUint64(nil, uint64(n))
|
||||
}
|
||||
|
||||
@ -29,8 +29,7 @@ func (s Store[T]) Get(key []byte) (value []byte, err error) {
|
||||
if found {
|
||||
return
|
||||
}
|
||||
// after we get it from parent store, we cache it.
|
||||
// if it is not found in parent store, we still cache it as nil.
|
||||
// if not found in the changeset, then check the parent.
|
||||
value, err = s.parent.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
120
store/cachekv/branch_bench_test.go
Normal file
120
store/cachekv/branch_bench_test.go
Normal file
@ -0,0 +1,120 @@
|
||||
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))
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user