go使用sync.Pool的性能对比

在业务代码编码中,涉及到经常用前创建,用后销毁的资源,为了提高性能,减少内存分配,减轻GC压力,自然而然地就会联想到使用对象池的应用。

go在很多方面都有着sync.Pool的应用,我们经常使用的fmt.Println("balabala"),其实也用到了sync.Pool,不信可以自己去阅读源码。

之前在用gin重构项目代码时,学习到gin.Context在处理新请求的时候,也是用到了sync.Pool复用context,减少内存分配,今天我们来看看使用sync.Pool和不用sync.Pool的的性能对比测试。

sync.Pool的使用其实也比较简单,

  • 1.创建对象池
  • 2.用时Get
  • 3.用完Put

不说废话,看代码:

package syncpool

import (
	"sync"
	"testing"
)

type person struct {
	age int
}

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

// no pool
func BenchmarkWithoutPool(b *testing.B) {
	var p *person
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j := 0; j < 10000; j++ {
			p = new(person)
			p.age = 23
		}
	}
}

// pool
func BenchmarkWithPool(b *testing.B) {
	var p *person
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j := 0; j < 10000; j++ {
			p = personpool.Get().(*person)
			p.age = 23
			personpool.Put(p)
		}
	}
}

以下是测试结果:

从测试结果看,确实遇到需要频繁创建对象的场景,如果用了sync.Pool对象池,结果竟然相差那么大,比如性能上,用pool的操作耗时几乎是不用pool的50%,而在内存分配上,由于pool复用对象,更是做到了0分配,说明sync.Pool的使用可以大大优化我们的代码,遇到相应的开发场景还不用上呢!

posted on 2022-12-20 11:09  进击的davis  阅读(236)  评论(0编辑  收藏  举报

导航