Go1.24 新特性:sync.Map 性能提高、Go mod 增加 tool 指令、Net/Http 協(xié)議優(yōu)化等
大家好,我是煎魚(yú)。
今天給大家繼續(xù)介紹 Go1.24 的新特性。
sync.Map 性能優(yōu)化
由 @Michael Knyszek 大佬提出的提案:
圖片
其首先在 unique 包中添加了 HashTrieMap。隨后在很多場(chǎng)景下,發(fā)現(xiàn)比傳統(tǒng)的 Map 性能和速度高效很多。
因此 Go 核心團(tuán)隊(duì)重新實(shí)現(xiàn)了 sync.Map 基于 HashTrieMap 實(shí)現(xiàn)方案。在本次的新版本 Go1.24 中,sync.Map 已經(jīng)改為并發(fā)的 HashTrieMap 數(shù)據(jù)結(jié)構(gòu)。在性能上有了顯著的提高。
如果你不希望使用,也可以通過(guò)配置 GOEXPERIMENT=nosynchashtriemap 來(lái)恢復(fù)到舊版本。
以下是兩者的前后性能對(duì)比:
/gomaxprocs: 4
│ before │ after │
│ sec/op │ sec/op vs base │
MapLoadMostlyHits 7.870n ± 1% 8.415n ± 3% +6.93% (p=0.002 n=6)
MapLoadMostlyMisses 7.210n ± 1% 5.314n ± 2% -26.28% (p=0.002 n=6)
MapLoadOrStoreBalanced 360.10n ± 18% 71.78n ± 2% -80.07% (p=0.002 n=6)
MapLoadOrStoreUnique 707.2n ± 18% 135.2n ± 4% -80.88% (p=0.002 n=6)
MapLoadOrStoreCollision 5.089n ± 201% 3.963n ± 1% -22.11% (p=0.002 n=6)
MapLoadAndDeleteBalanced 17.045n ± 64% 5.280n ± 1% -69.02% (p=0.002 n=6)
MapLoadAndDeleteUnique 14.250n ± 57% 6.452n ± 1% ~ (p=0.368 n=6)
MapLoadAndDeleteCollision 19.34n ± 39% 23.31n ± 27% ~ (p=0.180 n=6)
MapRange 3.055μ ± 3% 1.918μ ± 2% -37.23% (p=0.002 n=6)
MapAdversarialAlloc 245.30n ± 6% 14.90n ± 23% -93.92% (p=0.002 n=6)
MapAdversarialDelete 143.550n ± 2% 8.184n ± 1% -94.30% (p=0.002 n=6)
MapDeleteCollision 9.199n ± 65% 3.165n ± 1% -65.59% (p=0.002 n=6)
MapSwapCollision 164.7n ± 7% 108.7n ± 36% -34.01% (p=0.002 n=6)
MapSwapMostlyHits 33.12n ± 15% 35.79n ± 9% ~ (p=0.180 n=6)
MapSwapMostlyMisses 604.5n ± 5% 280.2n ± 7% -53.64% (p=0.002 n=6)
MapCompareAndSwapCollision 96.02n ± 40% 69.93n ± 24% -27.17% (p=0.041 n=6)
MapCompareAndSwapNoExistingKey 6.345n ± 1% 6.202n ± 1% -2.24% (p=0.002 n=6)
MapCompareAndSwapValueNotEqual 6.121n ± 3% 5.564n ± 4% -9.09% (p=0.002 n=6)
MapCompareAndSwapMostlyHits 44.21n ± 13% 43.46n ± 11% ~ (p=0.485 n=6)
MapCompareAndSwapMostlyMisses 33.51n ± 6% 13.51n ± 5% -59.70% (p=0.002 n=6)
MapCompareAndDeleteCollision 27.85n ± 104% 31.02n ± 26% ~ (p=0.180 n=6)
MapCompareAndDeleteMostlyHits 50.43n ± 33% 109.45n ± 8% +117.03% (p=0.002 n=6)
MapCompareAndDeleteMostlyMisses 27.17n ± 7% 11.37n ± 3% -58.14% (p=0.002 n=6)
MapClear 300.2n ± 5% 124.2n ± 8% -58.64% (p=0.002 n=6)
geomean 50.38n 25.79n -48.81%
go.mod 新增 tool 指示符
由 @Michael Tibben 大佬提出的新提案《Proposal: Adding tool dependencies to go.mod[1]》:
圖片
問(wèn)題的背景是:
- Go 開(kāi)發(fā)者經(jīng)常使用由 Go 編寫(xiě)并作為 Go 模塊分發(fā)的工具。例如:golang.org/x/tools/cmd/stringer 或 github.com/kyleconroy/sqlc。
- 但是當(dāng)前對(duì)這些 Go 開(kāi)發(fā)的工具的模塊管理支持相對(duì)薄弱。沒(méi)法很好的進(jìn)行周知和管理。
為了解決這一個(gè)問(wèn)題,提案作者提議在 go.mod 文件中引入一個(gè)新的 tool 指令,使工具開(kāi)發(fā)的作者能夠定義工具所需的模塊和相關(guān)版本。
go.mod 文件的例子如下:
go 1.24
tool (
golang.org/x/tools/cmd/stringer
./cmd/migrate
)
等效于:
go 1.24
tool golang.org/x/tools/cmd/stringer
tool ./cmd/migrate
在使用中,我們也可以在命令行編寫(xiě) go get 命令往 go.mod 文件追加:
go get -tool golang.org/x/tools/cmd/stringer
會(huì)是以下效果:
module example
go 1.24
tool golang.org/x/tools/cmd/stringer
...
本次通過(guò)在 go.mod 中引入 tool 指令,開(kāi)發(fā)者們可以更方便地管理項(xiàng)目所需的工具,確保團(tuán)隊(duì)成員使用相同版本的工具,避免版本不一致的問(wèn)題。
net/http Protocols 使用優(yōu)化
在以往的 net/http 標(biāo)準(zhǔn)庫(kù)中,提案原作者 @Damien Neil 認(rèn)為原有的用于選擇協(xié)議版本的 API 容易混淆、不一致、暴露內(nèi)部實(shí)現(xiàn)細(xì)節(jié),而且不能很好地推廣到其他協(xié)議版本。
圖片
因此新提案作者建議用一種單一、清晰的機(jī)制取代它們,并允許未來(lái)進(jìn)行擴(kuò)展。
采取的方式是提供以下新方法:
type Protocols struct { ... }
func (p *Protocols) HTTP1() bool
func (p *Protocols) HTTP2() bool
func (p *Protocols) HTTP3() bool
func (p *Protocols) SetHTTP1(ok bool)
func (p *Protocols) SetHTTP2(ok bool)
func (p *Protocols) SetHTTP3(ok bool)
代碼例子:
...
t.Protocols = new(http.Protocols)
t.Protocols.SetHTTP1(true)
t.Protocols.SetHTTP2(true)
&http.Client{Transport: t}
...
總結(jié)
本次這部分的 Go1.24 新特性中,針對(duì) sync.map 也進(jìn)行了綜合性能優(yōu)化。綜合之前文章提到的 map 的綜合性能提高。本次 Go1.24 對(duì)于較為常用的兩個(gè)數(shù)據(jù)結(jié)構(gòu)都有了明確的提高。是非常贊的!
另外本文也提及了 go.mod 的 tools 和 net/http Protocols 的使用優(yōu)化,也算是一些小點(diǎn)的優(yōu)化了。