介紹
因為它很快。通過文章底部存儲庫中的基準測試可以減少 4982 倍的內存占用。
Comparing pool performance. Less than better.
相比之下, Pool 的性能更快更好。
Ok, 這究竟是怎麼回事呢?
垃圾回收定期執行。如果你的代碼不斷地在一些數據結構中分配內存然後釋放它們,這就會導致收集器的不斷工作,使得更多的內存和 CPU 被用來在初始化結構體時分配資源。
對sync/pool.go[1] 的描述如下:
Pool 是一組可以單獨保存和檢索的臨時對象。
Pool 可以安全地同時使用多個 Goroutine。
sync.Pool允許我們重用內存而非重新分配。
此外,如果你使用的 http 伺服器接收帶有 JSON 請求體的 post 請求,並且它必須被解碼到結構體中,你可以使用 sync.Pool 來節省內存並減少伺服器響應時間。
sync.Pool 用法
sync.Pool 構造很簡單:
var bufferPool = sync.Pool{
\tNew: func() interface{} {
\t\treturn new(bytes.Buffer)
\t},
}
現在你將會創建一個 Pool 和新的緩衝區。你可以這樣創建第一個緩衝區:
buffer := bufferPool.Get().(*bytes.Buffer)
get 方法會返回 Pool 中已存在的 *bytes.Buffer,否則將調用 New 方法來初始化新的 *bytes.Buffer
但在緩衝區使用後,你必須將其重置並放回 Pool 中:
buffer.Reset()
bufferPool.Put(buffer)
基準測試
將 JSON 編碼為 bytes.Buffer
// 對 JSON 編碼的代碼段
BenchmarkReadStreamWithPool-8 5000000 384 ns/op 0 B/op 0 allocs/op
BenchmarkReadStreamWithoutPool-8 3000000 554 ns/op 160 B/op 2 allocs/op
我們得到了 44% 的性能提升並且節省了非常多的內存 (160B/ops vs 0B/ops)。
將位元組寫入 bufio.Writer
BenchmarkWriteBufioWithPool-8 10000000 123 ns/op 128 B/op 2 allocs/op
BenchmarkWriteBufioWithoutPool-8 2000000 651 ns/op 4288 B/op 4 allocs/op
我們得到了 5 倍性能提升並且減少了 32 倍內存使用。
將 JSON 解碼為 struct
BenchmarkJsonDecodeWithPool-8 1000000 1729 ns/op 1128 B/op 8 allocs/op
BenchmarkJsonDecodeWithoutPool-8 1000000 1751 ns/op 1160 B/op 9 allocs/op
因為 JSON 解碼操作太難,我們的性能只提升了 1%,我們無法通過重用結構體得到正常的提升。
Gzip 位元組
BenchmarkWriteGzipWithPool-8 500000 2339 ns/op 162 B/op 2 allocs/op
BenchmarkWriteGzipWithoutPool-8 10000 105288 ns/op 807088 B/op 16 allocs/op
等等,什麼?性能提升了 45 倍並且內存使用量減少了 4982 倍。
總結
務必使用 sync.Pool !它確實可以節省內存並提高應用程式的性能。
基準測試的 Github 存儲庫在這裡[2]。
via: https://medium.com/@Mnwa/why-you-should-like-sync-pool-2c7960c023ba
作者:Mnwa Mnowich[3]譯者:RookieWilson[4]校對:polaris1119[5]
本文由 GCTT[6] 原創編譯,Go 中文網[7] 榮譽推出
喜歡本文的朋友,歡迎關注「Go語言中文網」:
文中連結
[1]sync/pool.go: https://golang.org/src/sync/pool.go
[2]這裡: https://github.com/Mnwa/GoBench
[3]Mnwa Mnowich: https://medium.com/@Mnwa
[4]RookieWilson: https://github.com/RookieWilson
[5]polaris1119: https://github.com/polaris1119
[6]GCTT: https://github.com/studygolang/GCTT
[7]Go 中文網: https://studygolang.com/