go 库之 patrickmn/go-cache
一、代码仓
https://github.com/patrickmn/go-cache
二、概述
patrickmn/go-cache 是一个轻量级、线程安全的内存缓存库,基于 Go map 时间戳过期策略,轻量、易用。
三、主要特性
- 适合在单进程缓存临时数据(例如配置、计算结果、短期会话等)
- 每个条目可设置过期时间(或永久),有可选的后台清理(janitor)周期用于移除过期条目
- 提供基本的缓存操作(Set/Get/Add/Replace/Delete/Flush/Items)和过期回调(OnEvicted)
- 支持把缓存序列化到文件并恢复
- 并发安全,内部使用 RWMutex 互斥锁保证多 goroutine 访问安全
四、注意事项
- 值类型 vs 指针:缓存存储 interface{},将大结构体以值传入会导致每次装箱/拷贝并触发堆分配(性能/内存开销明显),对大型对象优先使用指针 &Struct{}
- 内存管理:go-cache 不限制缓存大小,高负载或大量条目会占用大量内存并可能触发 GC,必要时在业务层限制条目数
五、关于值类型与指针的 Benchmark 基线测试
单测代码
type LargeStruct struct {
Data [1000]int64 // 大型结构体,约8KB
}
// BenchmarkSetPointer 测试指针方式
func BenchmarkSetPointer(b *testing.B) {
c := New(time.Minute, time.Minute)
large := &LargeStruct{}
for i := 0; i < b.N; i++ {
c.Set("key", large, time.Minute)
}
}
// BenchmarkSetValue 测试值方式
func BenchmarkSetValue(b *testing.B) {
c := New(time.Minute, time.Minute)
large := LargeStruct{}
for i := 0; i < b.N; i++ {
c.Set("key", large, time.Minute)
}
}
执行 Benchmark
[master*] go test -bench "BenchmarkSetPointer|BenchmarkSetValue" -run '^$' -benchmem
goos: darwin
goarch: arm64
pkg: go-cache
cpu: Apple M3 Pro
BenchmarkSetPointer-12 25672538 45.69 ns/op 0 B/op 0 allocs/op
BenchmarkSetValue-12 1573534 758.4 ns/op 8192 B/op 1 allocs/op
PASS
ok go-cache 4.312s解析:
指针:平均每次操作耗时 45.69 纳秒,平均堆上字节数为 0 字节,平均堆分配次数为 0 次
值:平均每次操作约 758.4 纳秒,平均堆上分配约 8192 字节,平均堆分配次数为 1 次
从数据可看到,指针比值传递快约 16.6 倍
打赏:
微信
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。