偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Go1.24 Map 引入了新的問題,預(yù)計(jì)將在 Go1.25 修復(fù)!

開發(fā) 前端
目前來看,該項(xiàng)問題點(diǎn)有較大概率在 Go1.25 得到解決或者緩解。畢竟這是 Go1.24 新引入進(jìn)來的問題。大家也能看出來,軟件設(shè)計(jì)沒有銀彈。選擇了 A,就會(huì)有 B 的短板。很多事情也是這樣的。

大家好,我是煎魚。

在之前 Go1.24 新特性中,Map 有了非常大的變化。在 Map 中使用 Swiss Table 來替換 Hashmap 的原始實(shí)現(xiàn)。

前文我在 《Go1.24 新特性:map 換引擎,性能顯著提高!》中有所介紹,帶來了顯著的綜合性能提高。

但也帶來了新的問題點(diǎn),今天分享給大家。有興趣的同學(xué)可以關(guān)注后續(xù)進(jìn)展。

問題點(diǎn)

近日 @Michael Pratt 發(fā)現(xiàn)了 Map 里引入的新問題點(diǎn):

圖片圖片

在 Go1.24 所引入的 swissmaps 中,map[int64]struct{} 的每個(gè)槽(slot)需要 16 字節(jié)空間,而不是預(yù)期的 8 字節(jié)。

而 map[int64]struct{} 是日常中用來占位表現(xiàn)最為常用的一個(gè)用法之一。

原因

造成這個(gè)現(xiàn)象的原因在于 Map 內(nèi)部定義存儲(chǔ)[1]方式的所造成的副作用:

type group struct {
      ctrl uint64
      slots [abi.SwissMapGroupSlots]struct {
          key  keyType
          elem elemType
      }
  }

原因在于:

  • elemType 是 struct{}:

Go 編譯器中的 struct 大小規(guī)則規(guī)定,如果 struct 以零大?。▃ero-size)類型結(jié)束,則該字段將獲得 1 字節(jié)的空間。

會(huì)設(shè)計(jì)這個(gè)機(jī)制的目的是:防止有人創(chuàng)建指向最后一個(gè)字段的指針,Go 編譯器不希望指針指向分配結(jié)束的位置。

  • keyType 需要 8 字節(jié)對齊。

劃重點(diǎn):最后一個(gè)字段 keyType 實(shí)際上使用了整整 8 字節(jié),這是 KVKVKVKV(K/V 一起存儲(chǔ)) 由于對齊要求而浪費(fèi)空間的最極端情況。

這個(gè)問題出現(xiàn)在了新的 Map 新引入的 swissmaps 中。

解決思路

實(shí)際上還是 @Michael Pratt,既發(fā)現(xiàn)問題,還提出如何解決問題。簡直是專業(yè)的大好人!其提出了新的 issues《runtime: map cold cache improvements[2]》:

圖片圖片

里面涉及的內(nèi)容物比較多。聚焦于本文問題點(diǎn),其主要通過:更改布局將所有鍵放在一起來解決這個(gè)問題。

K/V 放一起(KVKVKV)和所有 K 放一起(KKKVVV...,舊 Map 的做法),各有優(yōu)缺點(diǎn)。

下面對比提到的控制字(control word)是指與哈希表中每個(gè)槽(slot)對應(yīng)的一小段元數(shù)據(jù),常用于加速查找過程。

以下是具體不同的布局方式的對比:

1、鍵/值(K/V)一起存儲(chǔ):

  • 命中(Map hit):

控制字可能發(fā)生緩存未命中。

鍵比較可能發(fā)生緩存未命中。

在父調(diào)用中使用值時(shí)不會(huì)發(fā)生緩存未命中。

  • 未命中(Map miss):
  • 控制字可能發(fā)生緩存未命中。
  • 在誤判匹配(約 1%)時(shí),鍵比較可能發(fā)生緩存未命中。
  • 無值可用。

2、所有鍵(K)集中存儲(chǔ):

  • 命中(Map hit):

控制字可能發(fā)生緩存未命中。

鍵比較不會(huì)發(fā)生緩存未命中。

在父調(diào)用中使用值時(shí)可能發(fā)生緩存未命中(如果使用)。

  • 未命中(Map miss):
  • 控制字可能發(fā)生緩存未命中。
  • 在誤判匹配(約 1%)時(shí),鍵比較不會(huì)發(fā)生緩存未命中。
  • 無值可用。

社區(qū)反饋

這在國外的社區(qū)開發(fā)者中也有提到:

圖片圖片

反饋在 Go1.24 中 map[uint64]struct{} 的性能比 Go1.23 低 10%。

而 Prometheus 的維護(hù)者 @Bryan Boreham,在 Prometheus 項(xiàng)目中,也發(fā)現(xiàn)使用 Go1.24 時(shí)訪問大 Map 會(huì)使用更多的 CPU。

圖片圖片

其具體的使用的基準(zhǔn)測試結(jié)果如下:

go test -run XXX -bench 'BenchmarkLoadWLs' -cpuprofile=cpu.pprof ./tsdb/
goos: linux
goarch: amd64
pkg: github.com/prometheus/prometheus/tsdb
cpu: Intel(R) Core(TM) i7-14700K
BenchmarkLoadWLs/batches=1000,seriesPerBatch=10000,samplesPerSeries=50,exemplarsPerSeries=0,mmappedChunkT=0,oooSeriesPct=0.000,oooSamplesPct=0.000,oooCapMax=0,missingSeriesPct=0.000-28                       1        25232921108 ns/op
PASS
ok      github.com/prometheus/prometheus/tsdb   33.909s

使用 Go1.23 版本,runtime.mapaccess1_fast64 的 CPU 占用時(shí)間為 82 秒;使用 Go1.24.2 版本,CPU 占用時(shí)間為 108 秒。

總結(jié)

目前來看,該項(xiàng)問題點(diǎn)有較大概率在 Go1.25 得到解決或者緩解。畢竟這是 Go1.24 新引入進(jìn)來的問題。

大家也能看出來,軟件設(shè)計(jì)沒有銀彈。選擇了 A,就會(huì)有 B 的短板。很多事情也是這樣的。

后續(xù)我們將會(huì)繼續(xù)保持關(guān)注,看看 Go 官方團(tuán)隊(duì)是否再次選擇把所有鍵(K)擺放在一起來解決這個(gè)問題點(diǎn),又或是引入新的解決方案。

參考資料

[1] 內(nèi)部定義存儲(chǔ): https://cs.opensource.google/go/go/+/master:src/cmd/compile/internal/reflectdata/map_swiss.go;l=30

[2] runtime: map cold cache improvements: https://github.com/golang/go/issues/70835

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2025-01-06 09:18:04

2025-04-29 08:59:37

2025-04-14 08:49:10

2025-02-12 08:50:22

2024-09-03 08:49:01

2025-05-12 08:58:14

GoDWARF5二進(jìn)制

2025-05-26 10:10:00

Go開發(fā)testing

2024-12-30 11:05:28

泛型Go類型別名

2025-06-16 08:54:01

macOS模式版本

2024-12-23 08:44:49

2025-01-20 08:51:32

2025-02-07 09:18:05

機(jī)制Go函數(shù)

2025-03-07 09:12:28

2025-05-06 08:00:35

2022-02-11 21:01:18

GoNetip網(wǎng)絡(luò)庫

2022-12-09 08:52:51

Go匿名接口

2025-04-28 05:00:00

2025-05-22 09:32:23

2025-02-08 11:00:33

2025-03-28 01:00:00

Go語言版本
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號