惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
雷峰网
雷峰网
V
Visual Studio Blog
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
IT之家
IT之家
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
月光博客
月光博客
A
About on SuperTechFans
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
J
Java Code Geeks
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale

博客园 - 海风吹

Chrome浏览器界面截图 linux文件锁flock【转】 golang 小知识-持续更新中 【转】Go Channels Golang文件名命名规则 Parquet存储格式 - 论文翻译【转】 预装的Office2016,文件图标表显示以及新建失败问题解决 方法 Gamma编码及Delta编码概述 时序数据库技术体系 – InfluxDB 多维查询之倒排索引 时序数据库技术体系 – InfluxDB TSM存储引擎之TSMFile 时间序列数据的存储和计算 - 开源时序数据库解析 时序数据库技术体系-时序数据存储模型设计 时序数据库-为万物互联插上一双翅膀 JMS和ActiveMQ的关系 JMS(Java消息服务)入门教程 Influxdb时序数据库阅读笔记 代码只是事业的 5%,程序员创业注意事项 golang 之 channel golang中context包学习
go的临时对象池--sync.Pool
海风吹 · 2018-05-25 · via 博客园 - 海风吹

作者:bigtom
链接:https://www.jianshu.com/p/2bd41a8f2254
來源:简书

一个sync.Pool对象就是一组临时对象的集合。Pool是协程安全的。
Pool用于存储那些被分配了但是没有被使用,而未来可能会使用的值,以减小垃圾回收的压力。一个比较好的例子是fmt包,fmt包总是需要使用一些[]byte之类的对象,golang建立了一个临时对象池,存放着这些对象,如果需要使用一个[]byte,就去Pool里面拿,如果拿不到就分配一份。
这比起不停生成新的[]byte,用完了再等待gc回收来要高效得多。

type buffer []byte
// pp是用于存储printer状态的一个结构体
type pp struct {
    buf buffer
    arg interface{}
    value reflect.Value
    fmt fmt
    reordered bool
    goodArgNum bool
    panicking bool
    erroring bool
}
//一个pp的对象池
var ppFree = sync.Pool{
    New: func() interface{} { return new(pp) },
}
// 分配一个新的pp或者拿一个缓存的。
func newPrinter() *pp {
    p := ppFree.Get().(*pp)
    p.panicking = false
    p.erroring = false
    p.fmt.init(&p.buf)
    return p
}

sync.Pool有两个公开的方法。一个是Get,另一个是Put。前者的功能是从池中获取一个interface{}类型的值,而后者的作用则是把一个interface{}类型的值放置于池中。

最简单的例子

// 一个[]byte的对象池,每个对象为一个[]byte
var bytePool = sync.Pool{
  New: func() interface{} {
    b := make([]byte, 1024)
    return &b
  },
}

func main() {
  a := time.Now().Unix()
  // 不使用对象池
  for i := 0; i < 1000000000; i++{
    obj := make([]byte,1024)
    _ = obj
  }
  b := time.Now().Unix()
  // 使用对象池
  for i := 0; i < 1000000000; i++{
    obj := bytePool.Get().(*[]byte)
    _ = obj
    bytePool.Put(obj)
  }
  c := time.Now().Unix()
  fmt.Println("without pool ", b - a, "s")
  fmt.Println("with    pool ", c - b, "s")
}

// without pool  34 s
// with    pool  24 s

上面代码的运行结果显示使用对象池很明显提升了性能