Skip to content

Instantly share code, notes, and snippets.

@yogesh-desai
Created May 30, 2019 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yogesh-desai/c50a4478dbde44cdef6605d82a5e236d to your computer and use it in GitHub Desktop.
Save yogesh-desai/c50a4478dbde44cdef6605d82a5e236d to your computer and use it in GitHub Desktop.
This compares various caches.
package gocachebenchmarks
import (
"fmt"
"strconv"
"sync"
"testing"
"time"
"github.com/allegro/bigcache"
"github.com/bluele/gcache"
"github.com/coocood/freecache"
hashicorp "github.com/hashicorp/golang-lru"
koding "github.com/koding/cache"
"github.com/muesli/cache2go"
cache "github.com/patrickmn/go-cache"
)
// We will be storing many short strings as the key and value
func BenchmarkKodingCache(b *testing.B) {
c := koding.NewMemoryWithTTL(time.Duration(60) * time.Second)
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
c.Set(strconv.FormatInt(int64(i), 10), i)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Get(strconv.FormatInt(int64(i), 10))
if err == nil {
_ = value
}
}
})
}
func BenchmarkHashicorpLRU(b *testing.B) {
// c := cache2go.Cache("test")
c, _ := hashicorp.New(10)
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
c.Add(i, i)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Get(i)
if err == true {
_ = value
}
}
})
}
func BenchmarkCache2Go(b *testing.B) {
c := cache2go.Cache("test")
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
c.Add(fmt.Sprintf("item%d", i), 1*time.Minute, value)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Value(fmt.Sprintf("item%d", i))
if err == nil {
_ = value
}
}
})
}
func BenchmarkGoCache(b *testing.B) {
c := cache.New(1*time.Minute, 5*time.Minute)
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
c.Add(fmt.Sprintf("item%d", i), value, cache.DefaultExpiration)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, found := c.Get(fmt.Sprintf("item%d", i))
if found {
_ = value
}
}
})
}
func BenchmarkFreecache(b *testing.B) {
c := freecache.NewCache(1024 * 1024 * 5)
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
c.Set([]byte(fmt.Sprintf("item%d", i)), []byte(value), 60)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Get([]byte(fmt.Sprintf("item%d", i)))
if err == nil {
_ = value
}
}
})
}
func BenchmarkBigCache(b *testing.B) {
c, _ := bigcache.NewBigCache(bigcache.Config{
// number of shards (must be a power of 2)
Shards: 1024,
// time after which entry can be evicted
LifeWindow: 10 * time.Minute,
// rps * lifeWindow, used only in initial memory allocation
MaxEntriesInWindow: 1000 * 10 * 60,
// max entry size in bytes, used only in initial memory allocation
MaxEntrySize: 500,
// cache will not allocate more memory than this limit, value in MB
// if value is reached then the oldest entries can be overridden for the new ones
// 0 value means no size limit
HardMaxCacheSize: 10,
})
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
c.Set(fmt.Sprintf("item%d", i), []byte(value))
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Get(fmt.Sprintf("item%d", i))
if err == nil {
_ = value
}
}
})
}
func BenchmarkGCache(b *testing.B) {
c := gcache.New(b.N).LRU().Build()
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
c.Set(fmt.Sprintf("item%d", i), value)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, err := c.Get(fmt.Sprintf("item%d", i))
if err == nil {
_ = value
}
}
})
}
// No expire, but helps us compare performance
func BenchmarkSyncMap(b *testing.B) {
var m sync.Map
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value := fmt.Sprintf("%20d", i)
m.Store(fmt.Sprintf("item%d", i), value)
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
value, found := m.Load(fmt.Sprintf("item%d", i))
if found {
_ = value
}
}
})
}
Output is as below,
$ go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: github.com/Xeoncross/go-cache-benchmark
BenchmarkKodingCache/Set-4 1000000 1855 ns/op 376 B/op 2 allocs/op
BenchmarkKodingCache/Get-4 2000000 626 ns/op 7 B/op 0 allocs/op
BenchmarkHashicorpLRU/Set-4 3000000 419 ns/op 102 B/op 4 allocs/op
BenchmarkHashicorpLRU/Get-4 20000000 86.7 ns/op 8 B/op 0 allocs/op
BenchmarkCache2Go/Set-4 1000000 2319 ns/op 466 B/op 10 allocs/op
BenchmarkCache2Go/Get-4 2000000 510 ns/op 39 B/op 3 allocs/op
BenchmarkGoCache/Set-4 1000000 2099 ns/op 279 B/op 5 allocs/op
BenchmarkGoCache/Get-4 3000000 379 ns/op 23 B/op 2 allocs/op
BenchmarkFreecache/Set-4 2000000 1013 ns/op 66 B/op 4 allocs/op
BenchmarkFreecache/Get-4 5000000 344 ns/op 24 B/op 2 allocs/op
BenchmarkBigCache/Set-4 1000000 1044 ns/op 99 B/op 4 allocs/op
BenchmarkBigCache/Get-4 3000000 457 ns/op 39 B/op 2 allocs/op
BenchmarkGCache/Set-4 1000000 1245 ns/op 207 B/op 8 allocs/op
BenchmarkGCache/Get-4 5000000 474 ns/op 39 B/op 3 allocs/op
BenchmarkSyncMap/Set-4 1000000 2139 ns/op 258 B/op 9 allocs/op
BenchmarkSyncMap/Get-4 5000000 314 ns/op 23 B/op 2 allocs/op
PASS
ok github.com/Xeoncross/go-cache-benchmark 66.188s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment