Skip to content

Commit

Permalink
move bench tests to readme
Browse files Browse the repository at this point in the history
  • Loading branch information
phuslu committed Jan 3, 2024
1 parent f5f9f3b commit 0b115df
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 365 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: '1.21'
check-latest: true
- name: Benchmark
- uses: actions/checkout@v4
- name: go mod tidy
run: |
mkdir bench
cd bench
awk '{if($0 ~ "// go test -v"){a=1;b=1};if($0 ~ "```" && b=1){b=0};if (a&&b) {print}}' ../README.md | tee bench_test.go
go mod tidy
go mod edit -replace github.com/phuslu/lru=../
- name: benchmark
working-directory: ./bench
run: |
go test -v -cpu=8 -run=none -bench=. -benchtime=5s -benchmem bench_test.go
198 changes: 197 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,203 @@ func main() {

### Benchmarks

A Performance result on keysize=16, cachesize=1000000, parallelism=32 with Read(90%)/Write(10%). Check [actions][actions] for more results and details.
A Performance result as below. Check [actions][actions] for more results and details.
<details>
<summary>benchmark on keysize=16, cachesize=1000000, parallelism=32 with read (90%) / write(10%)</summary>

```js
// go test -v -cpu=8 -run=none -bench=. -benchtime=5s -benchmem bench_test.go
package bench

import (
"fmt"
"testing"
"time"
_ "unsafe"

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"
otter "github.com/maypok86/otter"
ecache "github.com/orca-zhang/ecache"
phuslu "github.com/phuslu/lru"
)

const (
keysize = 16
cachesize = 1000000
parallelism = 32
writepercent = 10
)

var keymap = func() (x []string) {
x = make([]string, cachesize)
for i := 0; i < cachesize; i++ {
x[i] = fmt.Sprintf(fmt.Sprintf("%%0%dd", keysize), i)
}
return
}()

//go:noescape
//go:linkname fastrandn runtime.fastrandn
func fastrandn(x uint32) uint32

func BenchmarkCloudflareGet(b *testing.B) {
cache := cloudflare.NewMultiLRUCache(1024, cachesize/1024)
for i := 0; i < cachesize/2; i++ {
cache.Set(keymap[i], i, time.Now().Add(time.Hour))
}
b.SetParallelism(parallelism)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
expires := time.Now().Add(time.Hour)
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.Set(keymap[i], i, expires)
} else {
cache.Get(keymap[i])
}
}
})
}

func BenchmarkEcacheGet(b *testing.B) {
cache := ecache.NewLRUCache(1024, cachesize/1024, time.Hour)
for i := 0; i < cachesize/2; i++ {
cache.Put(keymap[i], i)
}
b.SetParallelism(parallelism)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.Put(keymap[i], i)
} else {
cache.Get(keymap[i])
}
}
})
}

func BenchmarkRistrettoGet(b *testing.B) {
cache, _ := ristretto.NewCache(&ristretto.Config{
NumCounters: cachesize, // number of keys to track frequency of (10M).
MaxCost: 2 << 30, // maximum cost of cache (2GB).
BufferItems: 64, // number of keys per Get buffer.
})
for i := 0; i < cachesize/2; i++ {
cache.SetWithTTL(keymap[i], i, 1, time.Hour)
}

b.SetParallelism(parallelism)
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.SetWithTTL(keymap[i], i, 1, time.Hour)
} else {
cache.Get(keymap[i])
}
}
})
}

func BenchmarkTheineGet(b *testing.B) {
cache, _ := theine.NewBuilder[string, int](cachesize).Build()
for i := 0; i < cachesize/2; i++ {
cache.SetWithTTL(keymap[i], i, 1, time.Hour)
}

b.SetParallelism(parallelism)
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.SetWithTTL(keymap[i], i, 1, time.Hour)
} else {
cache.Get(keymap[i])
}
}
})
}

func BenchmarkOtterGet(b *testing.B) {
cache, _ := otter.MustBuilder[string, int](cachesize).Build()
for i := 0; i < cachesize/2; i++ {
cache.SetWithTTL(keymap[i], i, time.Hour)
}

b.SetParallelism(parallelism)
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.SetWithTTL(keymap[i], i, time.Hour)
} else {
cache.Get(keymap[i])
}
}
})
}

func hashStringXXHASH(s string) uint32 {
return uint32(xxhash.Sum64String(s))
}

func BenchmarkFreelruGet(b *testing.B) {
cache, _ := freelru.NewSharded[string, int](cachesize, hashStringXXHASH)
for i := 0; i < cachesize/2; i++ {
cache.AddWithLifetime(keymap[i], i, time.Hour)
}

b.SetParallelism(parallelism)
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.AddWithLifetime(keymap[i], i, time.Hour)
} else {
cache.Get(keymap[i])
}
}
})
}

func BenchmarkPhusluGet(b *testing.B) {
cache := phuslu.New[string, int](cachesize)
for i := 0; i < cachesize/2; i++ {
cache.SetWithTTL(keymap[i], i, time.Hour)
}

b.SetParallelism(parallelism)
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
i := int(fastrandn(cachesize))
if i <= cachesize/writepercent {
cache.SetWithTTL(keymap[i], i, time.Hour)
} else {
cache.Get(keymap[i])
}
}
})
}
```
</details>

```
goos: linux
goarch: amd64
Expand Down
Loading

0 comments on commit 0b115df

Please sign in to comment.