Skip to content

Commit

Permalink
add: add dict for rotom db
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Jun 16, 2024
1 parent 3e7742d commit 73f78ad
Show file tree
Hide file tree
Showing 13 changed files with 730 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ run-gc:
GODEBUG=gctrace=1 go run .

test-cover:
go test -race -v -coverprofile=coverage.txt -covermode=atomic
go test ./... -race -v -coverprofile=coverage.txt -covermode=atomic
go tool cover -html=coverage.txt -o coverage.html
rm coverage.txt

Expand Down
4 changes: 2 additions & 2 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ func hgetallCommand(args []Arg) Value {
}

res := make([]Value, 0, 8)
hmap.Scan(func(key, value []byte) {
res = append(res, newBulkValue(key))
hmap.Scan(func(key string, value []byte) {
res = append(res, newBulkValue([]byte(key)))
res = append(res, newBulkValue(value))
})
return newArrayValue(res)
Expand Down
123 changes: 123 additions & 0 deletions dict/bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package dict

import (
"maps"
"testing"
)

const N = 100 * 10000

func getStdmap(num int) map[string][]byte {
m := map[string][]byte{}
for i := 0; i < num; i++ {
k, v := genKV(i)
m[k] = v
}
return m
}

func getDict(num int, options ...Options) *Dict {
opt := DefaultOptions
if len(options) > 0 {
opt = options[0]
}
m := New(opt)
for i := 0; i < num; i++ {
k, v := genKV(i)
m.Set(k, v)
}
return m
}

func BenchmarkSet(b *testing.B) {
b.Run("stdmap", func(b *testing.B) {
m := map[string][]byte{}
for i := 0; i < b.N; i++ {
k, v := genKV(i)
m[k] = v
}
})
b.Run("dict", func(b *testing.B) {
m := New(DefaultOptions)
for i := 0; i < b.N; i++ {
k, v := genKV(i)
m.Set(k, v)
}
})
}

func BenchmarkGet(b *testing.B) {
b.Run("stdmap", func(b *testing.B) {
m := getStdmap(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
k, _ := genKV(i)
_ = m[k]
}
})
b.Run("dict", func(b *testing.B) {
m := getDict(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
k, _ := genKV(i)
m.Get(k)
}
})
}

func BenchmarkScan(b *testing.B) {
b.Run("stdmap", func(b *testing.B) {
m := getStdmap(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for k, v := range m {
_, _ = k, v
}
}
})
b.Run("dict", func(b *testing.B) {
m := getDict(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.Scan(func(s string, b []byte, i int64) bool {
return true
})
}
})
}

func BenchmarkRemove(b *testing.B) {
b.Run("stdmap", func(b *testing.B) {
m := getStdmap(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
k, _ := genKV(i)
delete(m, k)
}
})
b.Run("dict", func(b *testing.B) {
m := getDict(N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
k, _ := genKV(i)
m.Remove(k)
}
})
}

func BenchmarkMigrate(b *testing.B) {
b.Run("stdmap", func(b *testing.B) {
m := getStdmap(100000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
maps.Clone(m)
}
})
b.Run("dict", func(b *testing.B) {
m := getDict(100000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.Migrate()
}
})
}
86 changes: 86 additions & 0 deletions dict/benchmark/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package main

import (
"flag"
"fmt"
"runtime"
"runtime/debug"
"time"

"github.com/cockroachdb/swiss"
"github.com/xgzlucario/rotom/dict"
)

var previousPause time.Duration

func gcPause() time.Duration {
runtime.GC()
var stats debug.GCStats
debug.ReadGCStats(&stats)
pause := stats.PauseTotal - previousPause
previousPause = stats.PauseTotal
return pause
}

func genKV(id int) (string, []byte) {
k := fmt.Sprintf("%08x", id)
return k, []byte(k)
}

func main() {
c := ""
entries := 0
flag.StringVar(&c, "cache", "dict", "map to bench.")
flag.IntVar(&entries, "entries", 2000*10000, "number of entries to test.")
flag.Parse()

fmt.Println(c)
fmt.Println("entries:", entries)

start := time.Now()
switch c {
case "dict":
m := dict.New(dict.DefaultOptions)
for i := 0; i < entries; i++ {
k, v := genKV(i)
m.Set(k, v)
}

case "stdmap":
type Item struct {
val []byte
ts int64
}
m := make(map[string]Item)
for i := 0; i < entries; i++ {
k, v := genKV(i)
m[string(k)] = Item{val: v, ts: 0}
}

case "swiss":
type Item struct {
val []byte
ts int64
}
m := swiss.New[string, Item](8)
for i := 0; i < entries; i++ {
k, v := genKV(i)
m.Put(string(k), Item{val: v, ts: 0})
}
}
cost := time.Since(start)

var mem runtime.MemStats
var stat debug.GCStats

runtime.ReadMemStats(&mem)
debug.ReadGCStats(&stat)

fmt.Println("alloc:", mem.Alloc/1024/1024, "mb")
fmt.Println("gcsys:", mem.GCSys/1024/1024, "mb")
fmt.Println("heap inuse:", mem.HeapInuse/1024/1024, "mb")
fmt.Println("heap object:", mem.HeapObjects/1024, "k")
fmt.Println("gc:", stat.NumGC)
fmt.Println("pause:", gcPause())
fmt.Println("cost:", cost)
}
Loading

0 comments on commit 73f78ad

Please sign in to comment.