Skip to content

Commit

Permalink
Benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
jimchen committed Aug 22, 2024
1 parent 5bd2c25 commit 52456ac
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 0 deletions.
224 changes: 224 additions & 0 deletions benchmark/lru_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package benchmark

import (
"testing"

"github.com/lovelysunlight/lru-go"
"github.com/pioz/faker"
)

type Object struct {
Str1 string
Str2 string
Str3 string
Str4 string
Age1 int
Age2 int
Age3 int
Age4 int
Bool1 bool
Bool2 bool
Bool3 bool
Bool4 bool

Obj1 *Object
Obj2 *Object
Obj3 *Object
Obj4 *Object

Map1 map[string]string
Map2 map[string]int
Map3 map[string]bool
Map4 map[string]float32
Map5 map[string]*Object
}

func BenchmarkLruCache_Put(b *testing.B) {
b.Run("int", func(b *testing.B) {
cache, _ := lru.New[int, int](10)
for i := 0; i < b.N; i++ {
cache.Put(i, i)
}
})

b.Run("float", func(b *testing.B) {
cache, _ := lru.New[int, float32](10)
for i := 0; i < b.N; i++ {
cache.Push(i, 1.1)
}
})

b.Run("bool", func(b *testing.B) {
cache, _ := lru.New[int, bool](10)
for i := 0; i < b.N; i++ {
cache.Push(i, true)
}
})

b.Run("string", func(b *testing.B) {
cache, _ := lru.New[int, string](10)
for i := 0; i < b.N; i++ {
cache.Push(i, "aaaaa")
}
})

b.Run("struct", func(b *testing.B) {
cache, _ := lru.New[int, *Object](10)
for i := 0; i < b.N; i++ {
cache.Push(i, &Object{
Str1: faker.String(),
Str2: faker.String(),
Str3: faker.String(),
Str4: faker.String(),
Age1: faker.Int(),
Age2: faker.Int(),
Age3: faker.Int(),
Age4: faker.Int(),
Bool1: faker.Bool(),
Bool2: faker.Bool(),
Bool3: faker.Bool(),
Bool4: faker.Bool(),

Obj1: &Object{},
Obj2: &Object{},
Obj3: &Object{},
Obj4: nil,

Map1: map[string]string{
faker.String(): faker.String(),
faker.String(): faker.String(),
faker.String(): faker.String(),
faker.String(): faker.String(),
},
Map2: map[string]int{
faker.String(): faker.Int(),
},
Map3: map[string]bool{
faker.String(): faker.Bool(),
},
Map4: map[string]float32{
faker.String(): faker.Float32(),
},
})
}
})
}

func BenchmarkLruCache_Get(b *testing.B) {
b.Run("int", func(b *testing.B) {
cache, _ := lru.New[int, int](10)
cache.Put(1, 1)
for i := 0; i < b.N; i++ {
cache.Get(1)
}
})

b.Run("float", func(b *testing.B) {
cache, _ := lru.New[int, float32](10)
cache.Put(1, 1.1)
for i := 0; i < b.N; i++ {
cache.Get(1)
}
})

b.Run("bool", func(b *testing.B) {
cache, _ := lru.New[int, bool](10)
cache.Put(1, true)
for i := 0; i < b.N; i++ {
cache.Get(1)
}
})

b.Run("string", func(b *testing.B) {
cache, _ := lru.New[int, string](10)
cache.Put(1, "aaaaa")
for i := 0; i < b.N; i++ {
cache.Get(1)
}
})
}

func BenchmarkLruCache_Peek(b *testing.B) {
b.Run("int", func(b *testing.B) {
cache, _ := lru.New[int, int](10)
cache.Put(1, 1)
for i := 0; i < b.N; i++ {
cache.Peek(1)
}
})

b.Run("float", func(b *testing.B) {
cache, _ := lru.New[int, float32](10)
cache.Put(1, 1.1)
for i := 0; i < b.N; i++ {
cache.Peek(1)
}
})

b.Run("bool", func(b *testing.B) {
cache, _ := lru.New[int, bool](10)
cache.Put(1, true)
for i := 0; i < b.N; i++ {
cache.Peek(1)
}
})

b.Run("string", func(b *testing.B) {
cache, _ := lru.New[int, string](10)
cache.Put(1, "aaaaa")
for i := 0; i < b.N; i++ {
cache.Peek(1)
}
})
}

func BenchmarkLruCache_Pop(b *testing.B) {
len := 10000000
b.Run("int", func(b *testing.B) {
cache, _ := lru.New[int, int](len)
for i := 0; i < len; i++ {
cache.Put(i, i)
}
b.Run("benchmark", func(b *testing.B) {
for i := 0; i < b.N; i++ {
cache.Pop(1)
}
})
})

b.Run("float", func(b *testing.B) {
cache, _ := lru.New[int, float32](len)
for i := 0; i < len; i++ {
cache.Put(i, 1.1)
}
b.Run("benchmark", func(b *testing.B) {
for i := 0; i < b.N; i++ {
cache.Pop(1)
}
})
})

b.Run("bool", func(b *testing.B) {
cache, _ := lru.New[int, bool](len)
for i := 0; i < len; i++ {
cache.Put(i, true)
}
b.Run("benchmark", func(b *testing.B) {
for i := 0; i < b.N; i++ {
cache.Pop(1)
}
})
})

b.Run("string", func(b *testing.B) {
cache, _ := lru.New[int, string](len)
for i := 0; i < len; i++ {
cache.Put(i, "aaaaa")
}
b.Run("benchmark", func(b *testing.B) {
for i := 0; i < b.N; i++ {
cache.Pop(1)
}
})
})
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require github.com/stretchr/testify v1.9.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pioz/faker v1.7.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pioz/faker v1.7.3 h1:Tez8Emuq0UN+/d6mo3a9m/9ZZ/zdfJk0c5RtRatrceM=
github.com/pioz/faker v1.7.3/go.mod h1:xSpay5w/oz1a6+ww0M3vfpe40pSIykeUPeWEc3TvVlc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23 changes: 23 additions & 0 deletions internal/deepcopy/deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ func Iface(iface interface{}) interface{} {
// Copy creates a deep copy of whatever is passed to it and returns the copy
// in an interface{}. The returned value will need to be asserted to the
// correct type.
//
//go:inline
func Copy[T any](src T) T {
var empty T
if reflect.DeepEqual(src, empty) {
Expand All @@ -27,6 +29,11 @@ func Copy[T any](src T) T {
// Make the interface a reflect.Value
original := reflect.ValueOf(src)

// If it's a basic type, we don't need to do anything special.
if isBasicType(original.Kind()) {
return src
}

// Make a copy of the same type as the original.
cpy := reflect.New(original.Type()).Elem()

Expand All @@ -37,6 +44,22 @@ func Copy[T any](src T) T {
return cpy.Interface().(T)
}

func isBasicType(kind reflect.Kind) bool {
switch kind {
case reflect.Bool:
fallthrough
case reflect.String:
fallthrough
case reflect.Float32, reflect.Float64:
fallthrough
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return true
default:
return false
}
}

// copyRecursive does the actual copying of the interface. It currently has
// limited support for what it can handle. Add as needed.
func copyRecursive(original, cpy reflect.Value) {
Expand Down

0 comments on commit 52456ac

Please sign in to comment.