You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
4.2 KiB

package provider_test
import (
"context"
"crypto/rand"
"fmt"
"math"
"math/big"
"testing"
"time"
glru "github.com/hashicorp/golang-lru"
"github.com/stretchr/testify/require"
"gitoa.ru/go-4devs/cache"
"gitoa.ru/go-4devs/cache/provider/lru"
"gitoa.ru/go-4devs/cache/provider/memcache"
"gitoa.ru/go-4devs/cache/provider/memory"
"gitoa.ru/go-4devs/cache/provider/pebble"
"gitoa.ru/go-4devs/cache/provider/redis"
"gitoa.ru/go-4devs/cache/provider/ristretto"
"gitoa.ru/go-4devs/cache/test"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
type provider struct {
name string
prov cache.Provider
}
func providers() []provider {
client, _ := glru.New(10000)
db, cl := test.PebbleDB()
defer cl()
return []provider{
{"encoding", memory.NewEncoding()},
{"map", memory.NewMap()},
{"shard", memory.NewMapShard()},
{"lru", lru.New(client)},
{"ristretto", ristretto.New(test.RistrettoClient())},
{"memcache", memcache.New(test.MemcacheClient())},
{"redis", redis.New(test.RedisClient())},
{"pebble", pebble.New(db)},
}
}
func randStringBytes(n int64) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[randInt64(int64(len(letterBytes)))]
}
return string(b)
}
func randInt64(max int64) int64 {
m := big.NewInt(max)
nBig, _ := rand.Int(rand.Reader, m)
return nBig.Int64()
}
func BenchmarkCacheGetRandomKeyString(b *testing.B) {
ctx := context.Background()
keysLen := 10000
for _, p := range providers() {
prov := p.prov
items := make([]*cache.Item, keysLen)
for i := 0; i < keysLen; i++ {
var val string
key := randStringBytes(55)
items[i] = cache.NewItem(key, &val)
require.Nil(b, prov(ctx, cache.OperationSet, cache.NewItem(key, "value: "+p.name, cache.WithTTL(time.Minute))))
}
b.Run(p.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = prov(ctx, cache.OperationGet, items[i%keysLen])
}
})
}
}
func BenchmarkCacheGetRandomKeyInt(b *testing.B) {
ctx := context.Background()
keysLen := 10000
for _, p := range providers() {
prov := p.prov
items := make([]*cache.Item, keysLen)
for i := 0; i < keysLen; i++ {
var val int64
key := randInt64(math.MaxInt64)
items[i] = cache.NewItem(key, &val)
require.Nil(b, prov(ctx, cache.OperationSet, cache.NewItem(key, randInt64(math.MaxInt64), cache.WithTTL(time.Minute))))
}
b.Run(p.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = prov(ctx, cache.OperationGet, items[i%keysLen])
}
})
}
}
func BenchmarkCacheGetStruct(b *testing.B) {
ctx := context.Background()
type testStruct struct {
Key string
val string
}
var val testStruct
item := cache.NewItem("key", &val)
for _, p := range providers() {
prov := p.prov
require.Nil(b, prov(ctx, cache.OperationSet, cache.NewItem("key", testStruct{Key: "key", val: ""}, cache.WithTTL(time.Minute))))
b.Run(p.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = prov(ctx, cache.OperationGet, item)
}
})
}
}
func BenchmarkCacheSetStruct(b *testing.B) {
ctx := context.Background()
type testStruct struct {
Key string
Val int
}
for _, p := range providers() {
prov := p.prov
b.Run(p.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
item := cache.NewItem(i, testStruct{"k", i}, cache.WithTTL(time.Hour))
_ = prov(ctx, cache.OperationSet, item)
}
})
}
}
func BenchmarkCacheGetParallel(b *testing.B) {
ctx := context.Background()
for _, p := range providers() {
prov := p.prov
key := fmt.Sprintf("key_%s", p.name)
val := fmt.Sprintf("value_%s", p.name)
item := cache.NewItem(key, &val, cache.WithTTL(time.Minute))
require.Nil(b, prov(ctx, cache.OperationSet, item))
b.Run(p.name, func(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_ = prov(ctx, cache.OperationGet, item)
}
})
})
}
}
func BenchmarkCacheSetParallel(b *testing.B) {
ctx := context.Background()
for _, p := range providers() {
prov := p.prov
key := fmt.Sprintf("key: %v", prov)
val := fmt.Sprintf("value: %v", prov)
b.Run(p.name, func(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
item := cache.NewItem(key, val, cache.WithTTL(time.Hour))
_ = prov(ctx, cache.OperationSet, item)
}
})
})
}
}