一、代码仓

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 倍

文章目录