Created
May 30, 2019 18:55
-
-
Save yogesh-desai/c50a4478dbde44cdef6605d82a5e236d to your computer and use it in GitHub Desktop.
This compares various caches.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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