otter is one of the fastest implementation but memory usage is too high, possible to reduce? #73
Closed
Description
otther completes at 26ns while phuslu completes at 29ns
./cachemain otter 10000000
otter 10000000 1216 MB 1600 MB 1431 MB
./cachemain nottl 10000000
nottl 10000000 355 MB 433 MB 438 MB
// memusage.go
package main
import (
"fmt"
"os"
"runtime"
"time"
"strconv"
theine "github.com/Yiling-J/theine-go"
"github.com/cespare/xxhash/v2"
cloudflare "github.com/cloudflare/golibs/lrucache"
ristretto "github.com/dgraph-io/ristretto"
freelru "github.com/elastic/go-freelru"
hashicorp "github.com/hashicorp/golang-lru/v2/expirable"
ccache "github.com/karlseguin/ccache/v3"
lxzan "github.com/lxzan/memorycache"
otter "github.com/maypok86/otter"
ecache "github.com/orca-zhang/ecache"
phuslu "github.com/phuslu/lru"
)
const keysize = 16
var keys []string
func main() {
name := os.Args[1]
cachesize, _ := strconv.Atoi(os.Args[2])
keys = make([]string, cachesize)
for i := 0; i < cachesize; i++ {
keys[i] = fmt.Sprintf(fmt.Sprintf("%%0%dd", keysize), i)
}
var o runtime.MemStats
runtime.ReadMemStats(&o)
map[string]func(int){
"nottl": SetupNottl,
//"phuslu": SetupPhuslu,
"freelru": SetupFreelru,
"ristretto": SetupRistretto,
"otter": SetupOtter,
"lxzan": SetupLxzan,
"ecache": SetupEcache,
"cloudflare": SetupCloudflare,
"ccache": SetupCcache,
"hashicorp": SetupHashicorp,
"theine": SetupTheine,
}[name](cachesize)
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%s\t%d\t%v MB\t%v MB\t%v MB\n",
name,
cachesize,
(m.Alloc-o.Alloc)/1048576,
(m.TotalAlloc-o.TotalAlloc)/1048576,
(m.Sys-o.Sys)/1048576,
)
}
func SetupNottl(cachesize int) {
cache := phuslu.New[string, int](cachesize)
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i)
}
}
/*
func SetupPhuslu(cachesize int) {
cache := phuslu.NewTTLCache[string, int](cachesize)
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i, time.Hour)
}
}
*/
func SetupFreelru(cachesize int) {
cache, _ := freelru.NewSharded[string, int](uint32(cachesize), func(s string) uint32 { return uint32(xxhash.Sum64String(s)) })
for i := 0; i < cachesize; i++ {
cache.AddWithLifetime(keys[i], i, time.Hour)
}
}
func SetupOtter(cachesize int) {
//cache, _ := otter.MustBuilder[string, int](cachesize).WithVariableTTL().Build()
cache, _ := otter.MustBuilder[string, int](cachesize).Build()
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i)
}
}
func SetupEcache(cachesize int) {
cache := ecache.NewLRUCache(1024, uint16(cachesize/1024), time.Hour)
for i := 0; i < cachesize; i++ {
cache.Put(keys[i], i)
}
}
func SetupRistretto(cachesize int) {
cache, _ := ristretto.NewCache(&ristretto.Config{
NumCounters: int64(10 * cachesize), // number of keys to track frequency of (10M).
MaxCost: int64(cachesize), // maximum cost of cache (1M).
BufferItems: 64, // number of keys per Get buffer.
})
for i := 0; i < cachesize; i++ {
cache.SetWithTTL(keys[i], i, 1, time.Hour)
}
}
func SetupLxzan(cachesize int) {
cache := lxzan.New[string, int](
lxzan.WithBucketNum(128),
lxzan.WithBucketSize(cachesize/128, cachesize/128),
lxzan.WithInterval(time.Hour, time.Hour),
)
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i, time.Hour)
}
}
func SetupTheine(cachesize int) {
cache, _ := theine.NewBuilder[string, int](int64(cachesize)).Build()
for i := 0; i < cachesize; i++ {
cache.SetWithTTL(keys[i], i, 1, time.Hour)
}
}
func SetupCloudflare(cachesize int) {
cache := cloudflare.NewMultiLRUCache(1024, uint(cachesize/1024))
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i, time.Now().Add(time.Hour))
}
}
func SetupCcache(cachesize int) {
cache := ccache.New(ccache.Configure[int]().MaxSize(int64(cachesize)).ItemsToPrune(100))
for i := 0; i < cachesize; i++ {
cache.Set(keys[i], i, time.Hour)
}
}
func SetupHashicorp(cachesize int) {
cache := hashicorp.NewLRU[string, int](cachesize, nil, time.Hour)
for i := 0; i < cachesize; i++ {
cache.Add(keys[i], i)
}
}