-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache_benchmark_test.go
More file actions
222 lines (180 loc) · 5.35 KB
/
cache_benchmark_test.go
File metadata and controls
222 lines (180 loc) · 5.35 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
package slog
import (
"fmt"
"sync"
"testing"
"github.com/darkit/slog/dlp"
"github.com/darkit/slog/internal/common"
)
// TestLRUCacheVsSyncMapPerformance 对比LRU缓存和sync.Map的性能
func TestLRUCacheVsSyncMapPerformance(t *testing.T) {
const iterations = 10000
const cacheSize = 1000
// 测试数据
testCases := make([]string, iterations)
for i := 0; i < iterations; i++ {
testCases[i] = fmt.Sprintf("test_format_string_%d_%%s", i%cacheSize)
}
t.Log("Performance comparison: LRU Cache vs sync.Map")
// 测试LRU缓存
lruCache := common.NewLRUStringCache(cacheSize)
t.Run("LRU_Cache", func(t *testing.T) {
start := testing.Benchmark(func(b *testing.B) {
for i := 0; i < b.N; i++ {
key := testCases[i%len(testCases)]
if val, ok := lruCache.GetString(key); !ok {
lruCache.PutString(key, "true")
} else {
_ = val
}
}
})
stats := lruCache.GetStats()
t.Logf("LRU Cache - Operations: %d, Avg per op: %v", iterations, start.NsPerOp())
t.Logf("LRU Cache - Cache size: %d, Hits: %d, Hit rate: %.2f%%",
stats.Size, stats.Hits, stats.HitRate*100)
})
// 测试sync.Map
syncMap := &sync.Map{}
counter := int64(0)
t.Run("Sync_Map", func(t *testing.T) {
start := testing.Benchmark(func(b *testing.B) {
for i := 0; i < b.N; i++ {
key := testCases[i%len(testCases)]
if val, ok := syncMap.Load(key); !ok {
syncMap.Store(key, "true")
counter++
} else {
_ = val
}
}
})
t.Logf("sync.Map - Operations: %d, Avg per op: %v", iterations, start.NsPerOp())
t.Logf("sync.Map - Stored items: %d", counter)
})
}
// BenchmarkFormatCacheLRU 基准测试LRU格式缓存
func BenchmarkFormatCacheLRU(b *testing.B) {
// 清理缓存
formatCache.Clear()
testMessages := []string{
"hello world",
"format %s test",
"multiple %s %d formats",
"no format specifiers",
"single %v format",
"complex %s format with %d numbers and %v values",
"plain text message",
"another %s message",
"testing %d format",
"final %v test",
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
msg := testMessages[i%len(testMessages)]
formatLog(msg, "test", 123, "value")
}
b.StopTimer()
stats := formatCache.GetStats()
b.Logf("Final cache stats - Size: %d, Hits: %d, Hit rate: %.2f%%",
stats.Size, stats.Hits, stats.HitRate*100)
}
// BenchmarkDLPCacheLRU 基准测试DLP引擎的LRU缓存
func BenchmarkDLPCacheLRU(b *testing.B) {
// 创建DLP引擎实例
engine := dlp.NewDlpEngine()
engine.Enable()
testTexts := []string{
"联系电话:13812345678",
"邮箱地址:test@example.com",
"身份证号:110101199001011234",
"银行卡号:6222020000000000000",
"普通文本没有敏感信息",
"多种信息:手机13987654321,邮箱user@domain.com",
"IP地址:192.168.1.100",
"姓名:张三李四",
"网址:https://www.example.com",
"简单文本测试",
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
text := testTexts[i%len(testTexts)]
_ = engine.DesensitizeText(text)
}
b.StopTimer()
hits, misses := engine.GetCacheStats()
totalRequests := hits + misses
hitRate := 0.0
if totalRequests > 0 {
hitRate = float64(hits) / float64(totalRequests) * 100
}
b.Logf("DLP cache stats - Hits: %d, Misses: %d, Hit rate: %.2f%%",
hits, misses, hitRate)
}
// BenchmarkLRUCacheContention 测试LRU缓存的并发性能
func BenchmarkLRUCacheContention(b *testing.B) {
cache := common.NewLRUCache(1000)
// 预填充一些数据
for i := 0; i < 500; i++ {
cache.Put(fmt.Sprintf("key_%d", i), fmt.Sprintf("value_%d", i))
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
key := fmt.Sprintf("key_%d", i%1000)
// 混合读写操作 (80% 读, 20% 写)
if i%5 == 0 {
cache.Put(key, fmt.Sprintf("value_%d", i))
} else {
cache.Get(key)
}
i++
}
})
b.StopTimer()
stats := cache.GetStats()
b.Logf("Concurrent cache stats - Size: %d, Hit rate: %.2f%%",
stats.Size, stats.HitRate*100)
}
// TestLRUCacheMemoryEfficiency 测试LRU缓存的内存效率
func TestLRUCacheMemoryEfficiency(t *testing.T) {
const maxSize = 100
cache := common.NewLRUCache(maxSize)
// 添加超过容量的数据
for i := 0; i < maxSize*2; i++ {
cache.Put(fmt.Sprintf("key_%d", i), fmt.Sprintf("value_%d", i))
// 验证缓存大小不超过限制
if cache.Size() > maxSize {
t.Errorf("Cache size %d exceeds maximum %d", cache.Size(), maxSize)
}
}
// 验证最终大小等于容量
if cache.Size() != maxSize {
t.Errorf("Final cache size %d != max size %d", cache.Size(), maxSize)
}
// 验证LRU淘汰策略 - 早期的键应该被淘汰
earlyKeys := 0
lateKeys := 0
for i := 0; i < maxSize; i++ {
if cache.Contains(fmt.Sprintf("key_%d", i)) {
earlyKeys++
}
}
for i := maxSize; i < maxSize*2; i++ {
if cache.Contains(fmt.Sprintf("key_%d", i)) {
lateKeys++
}
}
t.Logf("Early keys remaining: %d, Late keys remaining: %d", earlyKeys, lateKeys)
// 大部分早期键应该被淘汰,大部分晚期键应该保留
if earlyKeys > maxSize/4 {
t.Errorf("Too many early keys remain: %d (expected < %d)", earlyKeys, maxSize/4)
}
if lateKeys < maxSize*3/4 {
t.Errorf("Too few late keys remain: %d (expected > %d)", lateKeys, maxSize*3/4)
}
stats := cache.GetStats()
t.Logf("Memory efficiency test - Final size: %d, Capacity: %d, Utilization: %.1f%%",
stats.Size, stats.Capacity, float64(stats.Size)/float64(stats.Capacity)*100)
}