forked from bpowers/approx-lru
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsharded_lru_test.go
132 lines (114 loc) · 2.25 KB
/
sharded_lru_test.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package lru
import (
"strconv"
"sync"
"testing"
"unsafe"
)
func TestNewSharded(t *testing.T) {
}
func TestShardSize(t *testing.T) {
if 128 != unsafe.Sizeof(shard[int]{}) {
t.Fatalf("expected shard to be 128-bytes in size")
}
}
func BenchmarkLRU_BigSharded(b *testing.B) {
var rngMu sync.Mutex
rng := newRand()
rngMu.Lock()
l, err := NewSharded[int64](128*1024, defaultShardCount)
if err != nil {
b.Fatalf("err: %v", err)
}
type traceEntry struct {
k string
v int64
}
trace := make([]traceEntry, b.N*2)
for i := 0; i < b.N*2; i++ {
n := rng.Int63() % (4 * 128 * 1024)
trace[i] = traceEntry{k: strconv.Itoa(int(n)), v: n}
}
rngMu.Unlock()
b.ResetTimer()
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
rngMu.Lock()
seed := rng.Intn(len(trace))
rngMu.Unlock()
var hit, miss int
i := seed
for pb.Next() {
// use a predictable if rather than % len(trace) to eek a little more perf out
if i >= len(trace) {
i = 0
}
t := trace[i]
if i%2 == 0 {
l.Add(t.k, t.v)
} else {
if _, ok := l.Get(t.k); ok {
hit++
} else {
miss++
}
}
i++
}
// b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
})
}
func BenchmarkShardedLRU_HotKey(b *testing.B) {
var rngMu sync.Mutex
rng := newRand()
rngMu.Lock()
l, err := NewSharded[int64](128*1024, defaultShardCount)
if err != nil {
b.Fatalf("err: %v", err)
}
type traceEntry struct {
k string
v int64
}
trace := make([]traceEntry, b.N*2)
for i := 0; i < b.N*2; i++ {
var n int64
switch i % 4 {
case 0, 1:
n = 0
case 2:
n = 1
default:
n = rng.Int63() % (4 * 128 * 1024)
}
trace[i] = traceEntry{k: strconv.Itoa(int(n)), v: n}
}
rngMu.Unlock()
b.ResetTimer()
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
rngMu.Lock()
seed := rng.Intn(len(trace))
rngMu.Unlock()
var hit, miss int
i := seed
for pb.Next() {
// use a predictable if rather than % len(trace) to eek a little more perf out
if i >= len(trace) {
i = 0
}
t := trace[i]
if i%2 == 0 {
l.Add(t.k, t.v)
} else {
if _, ok := l.Get(t.k); ok {
hit++
} else {
miss++
}
}
i++
}
// b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
})
}