亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go編程庫Sync.Pool用法示例詳解

 更新時間:2022年12月15日 11:29:48   作者:小馬別過河  
這篇文章主要為大家介紹了Go編程庫Sync.Pool用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

場景

go 如果頻繁地創(chuàng)建、銷毀對象(比如 http 服務的 json 對象,日志內容等),會對 GC 造成壓力。比如下面的 Log 函數(shù),在高并發(fā)情況下,需要頻繁地創(chuàng)建和銷毀 buffer。

func Log(w io.Writer, key, val string) {
	b := new(bytes.Buffer)
  // 按一定的格式打印日志,這一段不是重點
	b.WriteString(time.Now().UTC().Format(time.RFC3339))
	b.WriteByte(' ')
	b.WriteString(key)
	b.WriteByte('=')
	b.WriteString(val)
	b.WriteByte('\n')
	w.Write(b.Bytes())
}

這時候可以考慮復用這些 buffer。我們可以維護一個 buffer 的對象池,需要的時候從對象池拿 buffer,用完放回對象池。這時候就推薦使用 sync.Pool 了。

sync.Pool 維護著一組對象池,需要時從對象池拿對象,不需要放回對象池就可以了。它有這些特點:

  • 忙時會自動擴容對象池,閑時會自動縮容;
  • 線程安全;
  • 對象池的對象,會未經(jīng)通知地自動刪除;
  • 不能被 copy。

用法

創(chuàng)建

初始化時指定 New 方法。sync.Pool 會通過 New 方法創(chuàng)建對象池的對象。一般返回一個指針。

// 從對象池里取 buffer 時,如果池里沒 buffer了,則調用 New 創(chuàng)建一個新的。
var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}

GET & PUT

通過 Get 獲取對象池的對象。當使用完畢,通過 Put 把對象返回對象池。

  b := bufPool.Get().(*bytes.Buffer)  // 從對象池拿 buffer 對象
  // 操作對象,這個不重要
	b.Reset()
	b.WriteString(time.Now().UTC().Format(time.RFC3339))
  // 操作完放回對象池
	bufPool.Put(b)

優(yōu)化 Log 函數(shù)

Log 函數(shù)可以使用 sync.Pool 的優(yōu)化,代碼如下:

var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}
func LogWithPool(w io.Writer, key, val string) {
  // 從對象池拿 buffer 
	b := bufPool.Get().(*bytes.Buffer)
	b.Reset()
  // 按一定的格式打印日志,這一段不是重點
	b.WriteString(time.Now().UTC().Format(time.RFC3339))
	b.WriteByte(' ')
	b.WriteString(key)
	b.WriteByte('=')
	b.WriteString(val)
	b.WriteByte('\n')
	w.Write(b.Bytes())
  // 放回對象池
	bufPool.Put(b)
}

性能測試

我們對兩個函數(shù)進行性能測試

// 不使用 sync.Pool
func BenchmarkLog(b *testing.B) {
	writer := os.NewFile(0, os.DevNull)
	for n := 0; n < b.N; n++ {
		Log(writer, "path", "/search?a=flowers")
	}
}
// 使用 sync.Pool 復用
func BenchmarkLogWithPool(b *testing.B) {
	writer := os.NewFile(0, os.DevNull)
	for n := 0; n < b.N; n++ {
		LogWithPool(writer, "path", "/search?a=flowers")
	}
}

結果:

> go test -bench . -benchmem
goos: darwin
goarch: amd64
pkg: example/pool
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkLog-8                   1849365               635.0 ns/op           112 B/op          2 allocs/op
BenchmarkLogWithPool-8           1993304               614.4 ns/op            48 B/op          1 allocs/op
PASS
ok      example/pool    4.333s

相比之下,使用 Sync.Pool 和不使用的時候,內存的使用比為 48:112,優(yōu)化效果還是挺明顯的。

參考:

[1]. pkg.go.dev/sync#Pool

以上就是Go編程庫Sync.Pool用法示例詳解的詳細內容,更多關于Go庫Sync.Pool的資料請關注腳本之家其它相關文章!

相關文章

  • Golang簡介與基本語法的學習

    Golang簡介與基本語法的學習

    這篇文章主要介紹了Golang簡介與基本語法的學習,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 解決Go?Json?Unmarshal反序列化丟失數(shù)字精度問題

    解決Go?Json?Unmarshal反序列化丟失數(shù)字精度問題

    業(yè)務會使用?id生成器?產(chǎn)生的?分布式唯一ID,長度比較長,所以代碼反序列化時,會出現(xiàn)精度丟失問題,那如何解決呢,下面小編就來和大家詳細講講
    2023-08-08
  • go語言制作的zip壓縮程序

    go語言制作的zip壓縮程序

    這篇文章主要介紹了go語言制作的zip壓縮程序,其主體思路是首先創(chuàng)建一個讀寫緩沖,然后用壓縮器包裝該緩沖,用Walk方法來將所有目錄下的文件寫入zip,有需要的小伙伴參考下。
    2015-03-03
  • Go語言中程序是怎么編譯的實現(xiàn)

    Go語言中程序是怎么編譯的實現(xiàn)

    本文主要介紹了Go語言中程序是怎么編譯的實現(xiàn),深入探討Go語言的編譯機制和最新的模塊管理系統(tǒng)Go Modules的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • 通過函數(shù)如何將golang?float64?保留2位小數(shù)(方法匯總)

    通過函數(shù)如何將golang?float64?保留2位小數(shù)(方法匯總)

    這篇文章主要介紹了通過函數(shù)將golang?float64保留2位小數(shù),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Go語言正則表達式的使用詳解

    Go語言正則表達式的使用詳解

    正則表達式是一種進行模式匹配和文本操縱的功能強大的工具。這篇文章主要介紹了Go正則表達式使用,本文給大家介紹的非常詳細,對大家的工作或學習具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • go語言map字典刪除操作的方法

    go語言map字典刪除操作的方法

    這篇文章主要介紹了go語言map字典刪除操作的方法,實例分析了map字典操作的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 如何使用Go檢測用戶本地是否安裝chrome

    如何使用Go檢測用戶本地是否安裝chrome

    這篇文章主要為大家詳細介紹了如何使用Go檢測用戶本地是否安裝chrome,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-10-10
  • Golang實現(xiàn)優(yōu)雅的將struct轉換為map

    Golang實現(xiàn)優(yōu)雅的將struct轉換為map

    在項目實踐中,有時候我們需要將struct結構體轉為map映射表,然后基于map做數(shù)據(jù)裁剪或操作。那么下面我來介紹下常用的兩種轉換方式,希望對大家有所幫助
    2023-01-01
  • 深入理解Go語言對象池

    深入理解Go語言對象池

    對象池是一種在編程中用于優(yōu)化資源管理的技術,本文主要介紹了深入理解Go語言對象池,對象池通常通過sync.Pool包或自定義數(shù)據(jù)結構實現(xiàn),下面就來介紹一下
    2024-01-01

最新評論