sync.Pool 使用时先通过New设置返回数据函数,该函数决定Pool中存储的什么数据,提供了Get, Put
Get() 用于从对象池中获取对象,因为返回值时 interface{} 因此需要值类型转换
Put() 则是在对象使用完之后放回对象池
使用示例
声明对象池
//1.现有Student结构体type Student struct{
Name string
Age int32
Remark [1024]byte}//2.声明对象池,通过对象池返回指定对象, //只需要实现 New 函数即可。对象池中没有对象时,将会调用 New 函数创建var studentPool = sync.Pool{
New:func()interface{}{returnnew(Student)},}
Get() 用于从对象池中获取对象,因为返回值是 interface{},因此需要类型转换。
Put() 则是在对象使用完毕后,返回对象池
stu := studentPool.Get().(*Student)
json.Unmarshal(buf, stu)
studentPool.Put(stu)
funcBenchmarkUnmarshal(b *testing.B){for n :=0; n < b.N; n++{
stu :=&Student{}
json.Unmarshal(buf, stu)}}funcBenchmarkUnmarshalWithPool(b *testing.B){for n :=0; n < b.N; n++{
stu := studentPool.Get().(*Student)
json.Unmarshal(buf, stu)
studentPool.Put(stu)}}
var bufferPool = sync.Pool{
New:func()interface{}{return&bytes.Buffer{}},}var data =make([]byte,10000)funcBenchmarkBufferWithPool(b *testing.B){for n :=0; n < b.N; n++{
buf := bufferPool.Get().(*bytes.Buffer)
buf.Write(data)
buf.Reset()
bufferPool.Put(buf)}}funcBenchmarkBuffer(b *testing.B){for n :=0; n < b.N; n++{var buf bytes.Buffer
buf.Write(data)}}
type pp struct{
buf buffer
...}var ppFree = sync.Pool{
New:func()interface{}{returnnew(pp)},}// newPrinter allocates a new pp struct or grabs a cached one.funcnewPrinter()*pp {
p := ppFree.Get().(*pp)
p.panicking =false
p.erroring =false
p.wrapErrs =false
p.fmt.init(&p.buf)return p
}// free saves used pp structs in ppFree; avoids an allocation per invocation.func(p *pp)free(){ifcap(p.buf)>64<<10{return}
p.buf = p.buf[:0]
p.arg =nil
p.value = reflect.Value{}
p.wrappedErr =nil
ppFree.Put(p)}funcFprintf(w io.Writer, format string, a ...interface{})(n int, err error){
p :=newPrinter()
p.doPrintf(format, a)
n, err = w.Write(p.buf)
p.free()return}// Printf formats according to a format specifier and writes to standard output.// It returns the number of bytes written and any write error encountered.funcPrintf(format string, a ...interface{})(n int, err error){returnFprintf(os.Stdout, format, a...)}
type Pool struct{//实现了Locker接口的空结构体
noCopy noCopy
//本地固定大小per-P池,实际类型为[P]poolLocal ,有多少个P数组就有多大,也就是每个P维护了一个本地的poolLocal。
local unsafe.Pointer
//本地数组的大小
localSize uintptr//上一周期的局部
victim unsafe.Pointer
//已使用的数组大小
victimSize uintptr// New 方法在 Get 失败的情况下,选择性的创建一个值,Get就会返回该值, 否则返回nil
New func()interface{}}