Mygin上下文之sync.Pool复用
sync.Pool 的作用
先看看官方文档怎样说的吧,我截取了官方文档的第一句。
// A Pool is a set of temporary objects that may be individually saved and retrieved.
.....
- 简单翻译一下的意思是:池是一组可以单独保存和检索的临时对象。既然可以单独保存和检索的临时对象,对于大量重复地创建许多对象,造成 GC 的工作量巨大。而mygin的模式是 责任链模式 ,因此满足使用 sync.Pool。
- 一个 Pool 可以安全地由多个 goroutine 同时使用。池的目的是缓存已分配但未使用的项目以供以后重用,从而减轻垃圾回收器的压力。
- sync.Pool 是可伸缩的,同时也是并发安全的,其大小仅受限于内存的大小。sync.Pool 用于存储那些被分配了但是没有被使用,而未来可能会使用的值。这样就可以不用再次经过内存分配,可直接复用已有对象,减轻 GC 的压力,从而提升系统的性能。
以上都是源于官方文档翻译的,文档中还提到fmt包中,打印也使用了sync.Pool,感兴趣的可以点进源码查看。
sync.Pool 使用
sync.Pool 的使用方式非常简单:
只需要实现New函数即可。对象池中没有对象时,将会调用New函数创建,我使用了mygin中的context
创建
var contextPool = sync.Pool{
New: func() interface{} {
return new(Context)
},
}
使用和归还
c := contextPool.Get().(*Context)
json.Marshal(c)
contextPool.Put(c)
测试
func BenchmarkUnmarshal(b *testing.B) {
for n := 0; n < b.N; n++ {
c := &Context{}
json.Marshal(c)
}
}
func BenchmarkUnmarshalWithPool(b *testing.B) {
for n := 0; n < b.N; n++ {
c := contextPool.Get().(*Context)
json.Marshal(c)
contextPool.Put(c)
}
}
测试结果:
go test -bench . -benchmem
goos: linux
goarch: amd64
pkg: github.com/scott-pb/mygin
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
BenchmarkUnmarshal-8 5888780 208.1 ns/op 144 B/op 2 allocs/op
BenchmarkUnmarshalWithPool-8 7261801 165.0 ns/op 48 B/op 1 allocs/op
PASS
ok github.com/scott-pb/mygin 2.808s
在这个例子中,可以看出,使用了 sync.Pool 后,内存占用仅为未使用的 48/144= 1/3,对 GC 的影响就很大了。执行速度也快了,当然不同的设备测试结果也会不同。
测试源码
我把测试源码放在了mygin中 mygin/context_test.go
mygin使用sync.Pool
修改mygin/engine.go
修改engine.go中实例化conetxt的部分具体在ServeHTTP 方法中
修改前
//实例化一个下上文
c := &Context{
Request: r,
Writer: w,
Params: params,
handlers: handlers,
index: -1,
}
修改后
//从pool中取
c := e.pool.Get().(*Context)
c.Request = r
c.Writer = w
c.Params = params
c.handlers = handlers
c.index = -1
// 执行处理函数链
c.Next()
//归还到pool中
e.pool.Put(c)
mygin测试
main方法代码如下
package main
import (
"fmt"
"github.com/scott-pb/mygin"
"net/http"
)
func main() {
r := mygin.Default()
group := r.Group("/api")
group.GET("/test", func(c *mygin.Context) {
c.String(http.StatusOK, "success!\n")
})
err := r.Run(":8088")
if err != nil {
fmt.Println(err)
}
}
curl测试
curl -i http://localhost:8088/api/test
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Thu, 01 Feb 2024 05:08:52 GMT
Content-Length: 9
success!
这样mygin的context上下文就加入了Pool池,对于高并发情况下的GC压力会减轻不少。我设计的上下文中内容很少,随着功能的增多,效果会更加明显。
Mygin上下文之sync.Pool复用的更多相关文章
- [Go] sync.Pool 的实现原理 和 适用场景
摘录一: Go 1.3 的 sync 包中加入一个新特性:Pool. 官方文档可以看这里 http://golang.org/pkg/sync/#Pool 这个类设计的目的是用来保存和复用临时对象,以 ...
- Golang 临时对象池 sync.Pool
Go 1.3 的sync包中加入一个新特性:Pool.官方文档可以看这里http://golang.org/pkg/sync/#Pool 这个类设计的目的是用来保存和复用临时对象,以减少内存分配,降低 ...
- 深度解密 Go 语言之 sync.Pool
最近在工作中碰到了 GC 的问题:项目中大量重复地创建许多对象,造成 GC 的工作量巨大,CPU 频繁掉底.准备使用 sync.Pool 来缓存对象,减轻 GC 的消耗.为了用起来更顺畅,我特地研究了 ...
- 多图详解Go的sync.Pool源码
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码时14.4 Pool介绍 总所周知Go 是一个自动垃圾回收的编程语言 ...
- sync.Pool:提高Go语言程序性能的关键一步
1. 简介 本文将介绍 Go 语言中的 sync.Pool并发原语,包括sync.Pool的基本使用方法.使用注意事项等的内容.能够更好得使用sync.Pool来减少对象的重复创建,最大限度实现对象的 ...
- sync.Pool的使用
一定要搞明白sync.Pool的正确用法,避免出现以下问题: kline := this.pool.Get() defer this.pool.Put(kline) kline.UnMarshal(d ...
- 深入Golang之sync.Pool详解
我们通常用golang来构建高并发场景下的应用,但是由于golang内建的GC机制会影响应用的性能,为了减少GC,golang提供了对象重用的机制,也就是sync.Pool对象池. sync.Pool ...
- go语言学习--go的临时对象池--sync.Pool
一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用于存储那些被分配了但是没有被使用,而未来可能会使用的值,以减小垃圾回收的压力.一个比较好的例子是fmt包,fmt包总 ...
- golang sync.Pool包的使用和一些注意地方
package main; import ( "sync" "fmt" "net" "runtime" ) //sync ...
- sync.Pool 资源池
sync.Pool type Pool struct { // 可选参数New指定一个函数在Get方法可能返回nil时来生成一个值 // 该参数不能在调用Get方法时被修改 New func() in ...
随机推荐
- Codeforces Round #694 (Div. 2) A~D、E
比赛链接:Here 1471A. Strange Partition 题意: 给一个数组,数组中的所有元素可以任意合并,求数组的每个元素除以x上取整的和,求结果的最大值和最小值. 思路: 瞎猜.最小值 ...
- S3C2440移植uboot之裁剪和修改默认参数
上一节S3C2440移植uboot之支持DM9000移植uboot支持了网卡驱动,这节裁剪和修改uboot默认参数 目录 uboot的环境参数 修改uboot的默认环境变量 查看 default_ ...
- Ubuntu 安装 MinIO
MinIO是一个开源的高性能对象存储解决方案,支持多种安装方式,本例仅介绍最基础的单机安装方式. 下载安装文件 直接从MinIO官网下载安装文件. 下载服务端 wget https://dl.min. ...
- SpringMVC - 加载静态资源
静态资源过滤 spring-config.xml <!-- 3,(1)让Spring MVC不处理静态资源 .(2)加载静态资源,也称为资源过滤 --> <mvc:default-s ...
- web - 解决 formdata 打印空对象
获取单个值可以使用formData对象.get();而直接打印是看不到的.因为外界访问不到,你使用append方法后,对应的键值对就已经添加到表单里面了,你在控制台看到的是FormData原型,存储的 ...
- 【面试题精讲】Mysql如何实现乐观锁
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 文章更新计划 系列文章地址 在 MySQL 中,可以通过使用乐 ...
- [转帖]HAProxy 在 TiDB 中的最佳实践
https://docs.pingcap.com/zh/tidb/stable/haproxy-best-practices 本文介绍 HAProxy 在 TiDB 中的最佳配置和使用方法.HAPro ...
- [转帖]比较不同CPU下的分支预测
https://plantegg.github.io/2023/04/16/%E6%AF%94%E8%BE%83%E4%B8%8D%E5%90%8CCPU%E4%B8%8B%E7%9A%84%E5%8 ...
- [转帖]金仓数据库KingbaseES数据目录结构
KingbaseES数据库结构 [kingbase@postgresV8]$ tree -LP2data/ . ├── data │ ├── base # 存储用户创建的数据库文件及隶属于用户数据库的 ...
- [转帖]CPU Turbo&Cstate&Pstate简介
https://www.jianshu.com/p/eaefd1eb0ac6 测试环境 CPU 1 Intel(R) Xeon(R) Gold 5218 CPU @ 2.30GHz 16 3130 3 ...