封装
type Pool[T PoolItem[T]] struct {
p sync.Pool
}
// 需要实现接口
type PoolItem[T any] interface {
Reset()
}
func NewPool[T PoolItem[T]](t T) *Pool[T] {
return &Pool[T]{
p: sync.Pool{New: func() any {
return t
}},
}
}
func (p *Pool[T]) Get() T {
return p.p.Get().(T)
}
func (p *Pool[T]) Put(t T) {
t.Reset()
p.p.Put(t)
}
测试
type Person struct {
Id int
Name string
Remark [1024]byte
}
func (p *Person) Reset() {
p.Id = 0
p.Name = ""
}
var buf, _ = json.Marshal(Person{Id: 1331, Name: "Alice"})
// 测试1,不使用sync.Pool
func BenchmarkNormal(b *testing.B) {
for i := 0; i < b.N; i++ {
var person = &Person{}
json.Unmarshal(buf, person)
}
}
// 测试2,使用sync.Pool
func BenchmarkPool(b *testing.B) {
var p = NewPool(&Person{})
for i := 0; i < b.N; i++ {
var person = p.Get()
if person.Id != 0 {
b.Fatal("pool item not reset")
}
json.Unmarshal(buf, person)
p.Put(person)
}
}
测试结果
goos: darwin
goarch: amd64
pkg: candy
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
BenchmarkNormal-12 12478 103272 ns/op 1400 B/op 8 allocs/op
BenchmarkPool-12 12272 94301 ns/op 248 B/op 7 allocs/op
PASS
ok candy 4.665s
可见二者在运行次数相近的情况下,每次操作的平均纳秒数和每次操作分配的堆内存对象数量相近,但每次操作分配的内存字节数相差很多。