前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >​sync.Pool 使用

​sync.Pool 使用

作者头像
王小明_HIT
发布2021-07-27 16:34:35
5020
发布2021-07-27 16:34:35
举报
文章被收录于专栏:程序员奇点程序员奇点

sync.Pool 使用场景

保存和复用临时对象,减少内存分配,降低 GC 压力

例子

type Student struct {
 Name   string
 Age    int32
 Remark [1024]byte
}

var buf, _ = json.Marshal(Student{Name: "Geektutu", Age: 25})

func unmarsh() {
 stu := &Student{}
 json.Unmarshal(buf, stu)
}

json 反序列化在文本解析和网络通信过程中十分常见,当程序并发很高时,短时间内需要创建大量的临时变量,,这些对象分配在堆上,会给 GC 造成很大压力,严重影响程序性能。

sync.Pool 是可伸缩的,同时也是并发安全的,大小受限于内存大小。sync.Pool 用于存储那些被分配了但是没有被使用,但是未来可能被使用的值。这样可以不用再次分配内存,提高效率。

sync.Pool 是大小可伸缩的,高负载时会动态扩容,存放在池中对象不活跃会被自动清理。

如何使用

声明对象池

只要实现 New 函数即可,对象池中没有对象,那么会调用 New 函数创建

var studentPool = sync.Pool{
    New: func() interface{} { 
        return new(Student) 
    },
}

Get& Put


stu := studentPool.Get().(*Student)
json.Unmarshal(buf, stu)
studentPool.Put(stu)

  • Get() 用于从对象池中获取对象,因为返回值时 interface{} 因此需要值类型转换
  • Put() 则是在对象使用完之后放回对象池
struct 性能测试
package sync

import (
   "encoding/json"
   "sync"
   "testing"
)

type Student struct {
   Name   string
   Age    int32
   Remark [1024]byte
}

var studentPool = sync.Pool{New: func() interface{} {
   return new(Student)
}}

var buf, _ = json.Marshal(Student{Name: "Geektutu", Age: 25})

func BenchmarkUnmarshal(b *testing.B) {
   for n := 0; n < b.N; n++ {
      stu := &Student{}
      json.Unmarshal(buf, stu)
   }
}

func BenchmarkUnmarshalWithPool(b *testing.B) {
   for n := 0; n < b.N; n++ {
      stu := studentPool.Get().(*Student)
      json.Unmarshal(buf, stu)
      studentPool.Put(stu)
   }
}

执行命令

 go test -bench . -benchmem

执行结果如下:

goos: darwin
goarch: amd64
pkg: code.byted.org/wangmingming.hit/GoProject/main/gobase/sync
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkUnmarshal-12                      13280             94006 ns/op            1384 B/op          7 allocs/op
BenchmarkUnmarshalWithPool-12              12662             95211 ns/op             232 B/op          6 allocs/op
PASS

BenchmarkUnmarshal 每个循环用了 94006 纳秒,

结果项

含义

BenchmarkUnmarshal-12

BenchmarkUnmarshal 是测试的函数名 -12 表示GOMAXPROCS(线程数)的值为12

13280

表示一共执行了13280次,即b.N的值

94006.0 ns/op

表示平均每次操作花费了94006.0纳秒

1384/op

表示每次操作申请了1384 Byte的内存申请

7 allocs/op

表示每次操作申请了7次内存

可以看到 使用 sync.Pool 后,内存占用仅为未使用的 232/1384.

参考资料

  • https://geektutu.com/post/hpg-sync-pool.html
  • https://geektutu.com/post/high-performance-go.html
  • https://github.com/wangxiaoming/high-performance-go
  • https://geektutu.com/post/qa-golang-2.html#Q5-%E7%AE%80%E8%BF%B0-Go-%E8%AF%AD%E8%A8%80GC-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6-%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • sync.Pool 使用场景
  • 例子
  • 如何使用
    • 声明对象池
      • Get& Put
        • struct 性能测试
      • 参考资料
      相关产品与服务
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档