Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(serverv2): add benchmarks of (old) cacheKV vs branch #22497

Merged
merged 5 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions server/v2/stf/branch/bench_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package branch

import (
"encoding/binary"
"fmt"
"testing"

Expand All @@ -14,29 +15,61 @@ var (
)

func Benchmark_CacheStack_Set(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)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_ = bs.Set([]byte{0}, []byte{0})
sink = bs.Set([]byte{0}, []byte{0})
}
})
}
if sink != nil {
testinginprod marked this conversation as resolved.
Show resolved Hide resolved
b.Fatal("prevent compiler optimization")
}
}

func Benchmark_Get(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)
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("prevent compiler optimization")
testinginprod marked this conversation as resolved.
Show resolved Hide resolved
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add sink = nil

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

func Benchmark_GetSparse(b *testing.B) {
var sink any
testinginprod marked this conversation as resolved.
Show resolved Hide resolved
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("prevent compiler optimization")
}
}

func Benchmark_Iterate(b *testing.B) {
Expand Down Expand Up @@ -71,7 +104,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 {
Expand All @@ -81,3 +114,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))
}
3 changes: 1 addition & 2 deletions server/v2/stf/branch/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
116 changes: 116 additions & 0 deletions store/cachekv/branch_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
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) {
var sink any
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to global and to be reset after use.

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")
}
}

// Gets always different keys.
func Benchmark_GetSparse(b *testing.B) {
var sink any
testinginprod marked this conversation as resolved.
Show resolved Hide resolved
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("prevent compiler optimization")
}
}

func Benchmark_Iterate(b *testing.B) {
var keySink, valueSink any

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()
}
})
}

_ = keySink
_ = valueSink
}

// 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