sniper A simple and efficient thread-safe key/value store for Go

fastcache Fast thread-safe inmemory cache for big number of entries in Go. Minimizes GC overhead

Benchmark

code

Go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package main

import (
	"bytes"
	"github.com/VictoriaMetrics/fastcache"
	"github.com/recoilme/sniper"
	"testing"
)

// go test dbmc_test.go -bench=. -benchmem

var (
	mc    = fastcache.New(5 * 1024 * 1024)
	db, _ = sniper.Open(sniper.Dir("1"))

	kvs = [][]byte{[]byte("a"), []byte("b"), []byte("c"), []byte("a"), []byte("b"), []byte("c"),
		[]byte("d"), []byte("e"), []byte("f"), []byte("g"), []byte("h"), []byte("i"),
		[]byte("j"), []byte("k"), []byte("l"), []byte("m"), []byte("n"), []byte("o"),
		[]byte("p"), []byte("q"), []byte("r"), []byte("s"), []byte("t"), []byte("u"),
		[]byte("v"), []byte("w"), []byte("x"), []byte("y"), []byte("z"), []byte("z"),
	}
)

func BenchmarkMc(b *testing.B) {
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// set
		for j := 0; j < len(kvs); j += 2 {
			mc.Set(kvs[j], kvs[j+1])
		}
		// get
		for j := 0; j < len(kvs); j += 2 {
			v := mc.Get(nil, kvs[j])
			if !bytes.Equal(v, kvs[j+1]) {
				panic("not equal")
			}
		}
	}
}

func BenchmarkDb(b *testing.B) {
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// set
		for j := 0; j < len(kvs); j += 2 {
			_ = db.Set(kvs[j], kvs[j+1], 0)
		}
		// get
		for j := 0; j < len(kvs); j += 2 {
			v, _ := db.Get(kvs[j])
			if !bytes.Equal(v, kvs[j+1]) {
				panic("not equal")
			}
		}
	}
}

Output

plaintext:
1
2
3
BenchmarkMc-8   	  604740	      1894 ns/op	     120 B/op	      15 allocs/op
BenchmarkDb-8   	   14437	     81229 ns/op	    1200 B/op	      75 allocs/op
PASS