-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrlsw_bench_test.go
75 lines (61 loc) · 1.47 KB
/
rlsw_bench_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
package rlsw
import (
"testing"
"time"
)
// This is the fastest way, though it seems like it would create a lot of extra slices.
func (r *Limiter) clearExpiredOriginal(now time.Time) {
for len(r.timestamps) > 0 && now.Sub(r.timestamps[0]) > r.window {
r.timestamps = r.timestamps[1:]
}
}
func (r *Limiter) clearExpiredIndexBased(now time.Time) {
idx := 0
for idx < len(r.timestamps) && now.Sub(r.timestamps[idx]) > r.window {
idx++
}
r.timestamps = r.timestamps[idx:]
}
func (r *Limiter) clearExpiredBinary(now time.Time) {
if len(r.timestamps) == 0 {
return
}
// Binary search to find the index of the first non-expired timestamp
start, end := 0, len(r.timestamps)-1
for start <= end {
mid := start + (end-start)/2
if now.Sub(r.timestamps[mid]) > r.window {
start = mid + 1
} else {
end = mid - 1
}
}
// Remove expired timestamps
if start > 0 {
r.timestamps = r.timestamps[start:]
}
}
func BenchmarkClearExpired(b *testing.B) {
r := &Limiter{
timestamps: make([]time.Time, 1000),
window: time.Minute,
}
now := time.Now()
b.Run("Original", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.clearExpiredOriginal(now)
}
})
r.timestamps = make([]time.Time, 1000)
b.Run("IndexBasedLoop", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.clearExpiredIndexBased(now)
}
})
r.timestamps = make([]time.Time, 1000)
b.Run("BinarySearch", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.clearExpiredBinary(now)
}
})
}