日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

GoLang?sync.Pool簡介與用法_Golang

作者:胡桃姓胡,蝴蝶也姓胡 ? 更新時間: 2023-02-07 編程語言

使用場景

一句話總結:保存和復用臨時對象,減少內存分配,降低GC壓力

sync.Pool是可伸縮的,也是并發安全的,其大小僅受限于內存大小。sync.Pool用于存儲那些被分配了但是沒有使用,而未來可能會使用的值。這樣就可以不用再次經過內存分配,可直接復用已有對象,減輕GC的壓力,從而提升系統性能。

使用方法

聲明對象池

type Student struct {
   Name   string
   Age    int32
   Remark [1024]byte
}
func main() {
   var studentPool = sync.Pool{
      New: func() interface{} {
         return new(Student)
      },
   }
}

Get & Put

type Student struct {
   Name   string
   Age    int32
   Remark [1024]byte
}
var buf, _ = json.Marshal(Student{Name: "lxy", Age: 18})
func Unmarsh() {
   var studentPool = sync.Pool{
      New: func() interface{} {
         return new(Student)
      },
   }
   stu := studentPool.Get().(*Student)
   err := json.Unmarshal(buf, stu)
   if err != nil {
      return
   }
   studentPool.Put(stu)
}
  • Get()用于從對象池中獲取對象,因為返回值是interface{},因此需要類型轉換
  • Put()則是在對象使用完畢之后,返回對象池

性能測試

以下是性能測試的代碼:

package benchmem
import (
   "encoding/json"
   "sync"
   "testing"
)
type Student struct {
   Name   string
   Age    int32
   Remark [1024]byte
}
var buf, _ = json.Marshal(Student{Name: "lxy", Age: 18})
var studentPool = sync.Pool{
   New: func() interface{} {
      return new(Student)
   },
}
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: windows
goarch: amd64 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
pkg: ginTest ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
BenchmarkUnmarshal-8 ? ? ? ? ? ? ? 17004 ? ? ? ? ? ? 74103 ns/op ? ? ? ? ? ?1392 B/op ? ? ? ? ?8 allocs/op
BenchmarkUnmarshalWithPool-8 ? ? ? 17001 ? ? ? ? ? ? 71173 ns/op ? ? ? ? ? ? 240 B/op ? ? ? ? ?7 allocs/op
PASS
ok ? ? ?ginTest 3.923s

在這個例子中,因為 Student 結構體內存占用較小,內存分配幾乎不耗時間。而標準庫 json 反序列化時利用了反射,效率是比較低的,占據了大部分時間,因此兩種方式最終的執行時間幾乎沒什么變化。但是內存占用差了一個數量級,使用了 sync.Pool 后,內存占用僅為未使用的 240/1392 = 1/6,對 GC 的影響就很大了。

我們甚至在fmt.Printf的源碼里面也使用了sync.Pool進行性能優化!

原文鏈接:https://blog.csdn.net/qq_61039408/article/details/128498046

欄目分類
最近更新