精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

曹大帶我學(xué) Go之從 Map 的 Extra 字段談起

開(kāi)發(fā) 后端
對(duì)于這些 overflow 的 bucket,在 hmap 結(jié)構(gòu)體和 bmap 結(jié)構(gòu)體里分別有一個(gè) extra.overflow 和 overflow 字段指向它們。

[[416124]]

本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)桃花源」,作者小X 。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)桃花源公眾號(hào)。

你好,我是小X。

曹大最近開(kāi) Go 課程了,小X 正在和曹大學(xué) Go。

這個(gè)系列會(huì)講一些從課程中學(xué)到的讓人醍醐灌頂?shù)臇|西,撥云見(jiàn)日,帶你重新認(rèn)識(shí) Go。

熟悉 map 結(jié)構(gòu)體的讀者應(yīng)該知道,hmap 由很多 bmap(bucket) 構(gòu)成,每個(gè) bmap 都保存了 8 個(gè) key/value 對(duì):

hmap

有時(shí)落在同一個(gè) bmap 中的 key/value 太多了,超過(guò)了 8 個(gè),就會(huì)由溢出 bmap 來(lái)承接,即 overflow bmap(后面我們叫它 bucket)。溢出的 bucket 和原來(lái)的 bucket 形成一個(gè)“拉鏈”。

對(duì)于這些 overflow 的 bucket,在 hmap 結(jié)構(gòu)體和 bmap 結(jié)構(gòu)體里分別有一個(gè) extra.overflow 和 overflow 字段指向它們。

如果我們仔細(xì)看 mapextra 結(jié)構(gòu)體里對(duì) overflow 字段的注釋?zhuān)瑫?huì)發(fā)現(xiàn)這里有“文章”。

  1. type mapextra struct { 
  2.  overflow    *[]*bmap 
  3.  oldoverflow *[]*bmap 
  4.  
  5.  nextOverflow *bmap 

其中 overflow 這個(gè)字段上面有一大段注釋?zhuān)覀儊?lái)看看前兩行:

  1. // If both key and elem do not contain pointers and are inline, then we mark bucket 
  2. // type as containing no pointers. This avoids scanning such maps. 

意思是如果 map 的 key 和 value 都不包含指針的話(huà),在 GC 期間就可以避免對(duì)它的掃描。在 map 非常大(幾百萬(wàn)個(gè) key)的場(chǎng)景下,能提升不少性能。

那具體是怎么實(shí)現(xiàn)“不掃描”的呢?

我們知道,bmap 這個(gè)結(jié)構(gòu)體里有一個(gè) overflow 指針,它指向溢出的 bucket。因?yàn)樗且粋€(gè)指針,所以 GC 的時(shí)候肯定要掃描它,也就要掃描所有的 bmap。

而當(dāng) map 的 key/value 都是非指針類(lèi)型的話(huà),掃描是可以避免的,直接標(biāo)記整個(gè) map 的顏色(三色標(biāo)記法)就行了,不用去掃描每個(gè) bmap 的 overflow 指針。

但是溢出的 bucket 總是可能存在的,這和 key/value 的類(lèi)型無(wú)關(guān)。

于是就利用 hmap 里的 extra 結(jié)構(gòu)體的 overflow 指針來(lái) “hold” 這些 overflow 的 bucket,并把 bmap 結(jié)構(gòu)體的 overflow 指針類(lèi)型變成一個(gè) unitptr 類(lèi)型(這些是在編譯期干的)。于是整個(gè) bmap 就完全沒(méi)有指針了,也就不會(huì)在 GC 期間被掃描。

  1. overflow    *[]*bmap 

另一方面,當(dāng) GC 在掃描 hmap 時(shí),通過(guò) extra.overflow 這條路徑(指針)就可以將 overflow 的 bucket 正常標(biāo)記成黑色,從而不會(huì)被 GC 錯(cuò)誤地回收。

當(dāng)我們知道上面這些原理后,就可以利用它來(lái)對(duì)一些場(chǎng)景進(jìn)行性能優(yōu)化:

  1. map[string]int -> map[[12]byte]int 

因?yàn)?string 底層有指針,所以當(dāng) string 作為 map 的 key 時(shí),GC 階段會(huì)掃描整個(gè) map;而數(shù)組 [12]byte 是一個(gè)值類(lèi)型,不會(huì)被 GC 掃描。

我們用兩種方法來(lái)驗(yàn)證優(yōu)化效果。

主動(dòng)觸發(fā) GC

這里的測(cè)試代碼來(lái)自文章《盡量不要在大 map 中保存指針》[1]:

  1. func MapWithPointer() { 
  2.     const N = 10000000 
  3.     m := make(map[string]string) 
  4.     for i := 0; i < N; i++ { 
  5.         n := strconv.Itoa(i) 
  6.         m[n] = n 
  7.     } 
  8.     now := time.Now() 
  9.     runtime.GC()      
  10.     fmt.Printf("With a map of strings, GC took: %s\n"time.Since(now)) 
  11.  
  12.     // 引用一下防止被 GC 回收掉 
  13.     _ = m["0"
  14.  
  15. func MapWithoutPointer() { 
  16.     const N = 10000000 
  17.     m := make(map[int]int
  18.     for i := 0; i < N; i++ { 
  19.         str := strconv.Itoa(i) 
  20.         // hash string to int 
  21.         n, _ := strconv.Atoi(str) 
  22.         m[n] = n 
  23.     } 
  24.     now := time.Now() 
  25.     runtime.GC() 
  26.     fmt.Printf("With a map of int, GC took: %s\n"time.Since(now)) 
  27.  
  28.     _ = m[0] 
  29.  
  30. func TestMapWithPointer(t *testing.T) { 
  31.     MapWithPointer() 
  32.  
  33. func TestMapWithoutPointer(t *testing.T) { 
  34.     MapWithoutPointer() 

直接用了 2 個(gè)不同類(lèi)型的 map:前者 key 和 value 都是 string 類(lèi)型,后者 key 和 value 都是 int 類(lèi)型。整個(gè) map 大小為 1kw。

測(cè)試結(jié)果:

  1. === RUN   TestMapWithPointer 
  2. With a map of strings, GC took: 150.078ms 
  3. --- PASS: TestMapWithPointer (4.22s) 
  4. === RUN   TestMapWithoutPointer 
  5. With a map of int, GC took: 4.9581ms 
  6. --- PASS: TestMapWithoutPointer (2.33s) 
  7. PASS 

于是驗(yàn)證了 string 相對(duì)于 int 這種值類(lèi)型對(duì) GC 的消耗更大。正如這篇文章的標(biāo)題所說(shuō):

Go語(yǔ)言使用 map 時(shí)盡量不要在 big map 中保存指針。

用 pprof 看對(duì)象數(shù)

第二種方式就是直接開(kāi)個(gè) pprof 來(lái)看 heap profile。這次我們將 string 類(lèi)型的 key 優(yōu)化成數(shù)組類(lèi)型:

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "io" 
  6.  "net/http" 
  7.  _ "net/http/pprof" 
  8.  
  9. // var m = map[[12]byte]int{} 
  10. var m = map[string]int{} 
  11.  
  12. func init()  { 
  13.  for i := 0; i < 1000000; i++ { 
  14.   // var arr [12]byte 
  15.   // copy(arr[:], fmt.Sprint(i)) 
  16.   // m[arr] = i 
  17.  
  18.   m[fmt.Sprint(i)] = i 
  19.  } 
  20.  
  21. func sayHello(wr http.ResponseWriter, r *http.Request) { 
  22.  io.WriteString(wr ,"hello"
  23.  
  24. func main() { 
  25.  http.HandleFunc("/", sayHello) 
  26.  err := http.ListenAndServe(":8000", nil) 
  27.  if err != nil { 
  28.   fmt.Println(err) 
  29.  } 

注意,去掉代碼里的注釋即可將 key 從 string 優(yōu)化成數(shù)組類(lèi)型。

直接在 init 里構(gòu)建 map,然后開(kāi) pprof 看 profile:

key 為 string

key 為數(shù)組

對(duì)象數(shù)從 33w 下降到 1.5w,效果非常明顯。

map 的 key 和 value 要不要在 GC 里掃描,和類(lèi)型是有關(guān)的。數(shù)組類(lèi)型是個(gè)值類(lèi)型,string 底層也是指針。

不過(guò)要注意,key/value 大于 128B 的時(shí)候,會(huì)退化成指針類(lèi)型。

那么問(wèn)題來(lái)了,什么是指針類(lèi)型呢?**所有顯式 *T 以及內(nèi)部有 pointer 的對(duì)像都是指針類(lèi)型。

——來(lái)自董神的 map 優(yōu)化文章

關(guān)于超過(guò) 128 字節(jié)的情況,源碼里也有說(shuō)明:

  1. // Maximum key or elem size to keep inline (instead of mallocing per element). 
  2. maxKeySize  = 128 
  3. maxElemSize = 128 

總結(jié)

當(dāng) map 的 key/value 是非指針類(lèi)型時(shí),GC 不會(huì)對(duì)所有的 bucket 進(jìn)行掃描。如果線上服務(wù)使用了一個(gè)超大的 map ,會(huì)因此提升性能。

為了不讓 overflow 的 bucket 被 GC 錯(cuò)誤地回收掉,在 hmap 里用 extra.overflow 指針指向它,從而在三色標(biāo)記里將其標(biāo)記為黑色。

如果你用了 key 是 string 類(lèi)型的 map,并且恰好這些 string 是定長(zhǎng)的,那么就可以用 key 為數(shù)組類(lèi)型的 map 來(lái)優(yōu)化它。

通過(guò)主動(dòng)調(diào)用 GC 以及開(kāi) pprof 都可觀察優(yōu)化效果。

好了,這就是今天全部的內(nèi)容了~ 我是小X,我們下期再見(jiàn)~

歡迎關(guān)注曹大的 TechPaper 以及碼農(nóng)桃花源~

參考資料

[1]《盡量不要在大 map 中保存指針》: https://www.jianshu.com/p/5903323a7110

 

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)桃花源
相關(guān)推薦

2021-06-10 09:00:32

Go底層代碼

2021-06-07 10:47:02

GoGoexit函數(shù)

2021-06-01 09:27:53

Ast Go語(yǔ)言

2021-07-15 08:58:15

指定配置項(xiàng)Go

2021-05-20 08:59:47

Go調(diào)度本質(zhì)

2021-05-27 08:59:09

Go匯編命令

2022-01-05 08:56:20

Go火焰圖編程

2017-04-25 16:45:11

2022-11-02 08:36:35

ArgoAIOPS

2022-10-13 08:32:44

手機(jī)故障IO

2023-03-02 08:13:53

Oracle共享池監(jiān)控

2022-10-31 07:33:05

Javafor循環(huán)

2025-03-11 00:35:00

DeepSeektoC業(yè)務(wù)

2020-06-28 13:51:03

哈希map結(jié)構(gòu)

2018-02-07 17:32:54

情感分析

2022-04-06 08:58:39

歸并排序Go算法

2017-07-03 13:53:17

大數(shù)據(jù)大數(shù)據(jù)平臺(tái)數(shù)據(jù)治理

2017-04-17 08:44:43

構(gòu)造函數(shù)線程安全

2022-10-30 10:14:43

Java循環(huán)語(yǔ)句

2012-05-10 17:21:49

三星Tizen
點(diǎn)贊
收藏

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

夜夜爽久久精品91| 日韩欧美视频一区二区| 日韩精品成人一区| 国内黄色精品| 91麻豆精品国产91久久久久久久久| 欧美在线观看黄| 国产一级在线观看| 国产一区二区三区四区在线观看| 国模视频一区二区三区| 91麻豆制片厂| 国偷自产av一区二区三区| 欧美性猛交xxxxxxxx| 男人添女荫道口女人有什么感觉| 国产九九在线| 成人avav影音| 亚洲qvod图片区电影| 激情视频网站在线观看| 国内精品福利| 日韩最新在线视频| 亚洲成人网在线播放| 久久99成人| 欧美在线|欧美| 2018国产在线| av大大超碰在线| 亚洲国产成人自拍| 久久久久久久久久久一区 | 91老司机在线| 波多野结衣日韩| 99国产精品久久久久久久成人热| 久久久极品av| 国产91在线播放九色| 最新亚洲精品| 亚洲精品理论电影| 少妇熟女视频一区二区三区| 电影91久久久| 欧美猛男超大videosgay| 久久久久久久久久久免费视频| 少妇av在线| 亚洲欧美电影一区二区| 亚洲一区不卡在线| jizzjizz在线观看| 久久久不卡影院| 免费毛片一区二区三区久久久| 日本wwwxxxx| 国产成人精品一区二区三区四区 | 久久久久久成人精品| 国产精品av免费| 你懂的免费在线观看| 99视频在线精品| 国产98在线|日韩| www视频在线| 国产一二三精品| 91九色视频在线| 国产精品天天操| 国内精品视频666| 91在线色戒在线| av资源免费看| 国产69精品久久久久毛片| 91久久精品国产91久久性色tv| 精品人妻aV中文字幕乱码色欲| 国产精品综合二区| 成人免费在线一区二区三区| 亚洲AV无码乱码国产精品牛牛| 国产成人综合自拍| 国产伦视频一区二区三区| 日本波多野结衣在线| 99久久99精品久久久久久| 久久久99国产精品免费| 久久久久亚洲精品成人网小说| 怡红院一区二区| 奇米777国产一区国产二区| 亚洲精品久久久久中文字幕欢迎你 | 欧美少妇网站| 在线看国产一区二区| 玖玖爱视频在线| 国产精品日韩精品在线播放| 精品免费一区二区三区| 麻豆av免费观看| 成人激情开心网| 欧美成人在线影院| 天堂网一区二区三区| 视频一区视频二区在线观看| 成人精品一区二区三区电影黑人| 亚洲精品久久久久久久久久久久久久 | 五月天久久久| 久久久久久69| 日本免费精品视频| 久久99精品国产91久久来源| av成人在线电影| 黄色片免费在线| 亚洲免费观看高清在线观看| 两根大肉大捧一进一出好爽视频| 精品久久福利| 激情久久综合| 日韩精品在线免费播放| 91成人精品一区二区| 自拍欧美日韩| 日本一本a高清免费不卡| 91尤物国产福利在线观看| 不卡的看片网站| 一区二区三区我不卡| 国产高潮在线| 欧美日本在线播放| 久久精品综合视频| 午夜精品一区二区三区国产| 欧美在线观看网站| 国产chinasex对白videos麻豆| 久久亚洲私人国产精品va媚药| 国产av第一区| 免费在线观看一区| 亚洲精品720p| 黄色一级视频免费观看| 奇米色一区二区| 好看的日韩精品视频在线| 黄色av免费在线| 在线观看一区二区视频| 亚洲麻豆一区二区三区| 综合激情视频| 国产日韩欧美在线观看| 国产毛片在线看| 欧美日韩亚洲精品内裤| 色欲欲www成人网站| 久久综合99| 国产精品99久久久久久www| 天天摸天天干天天操| 亚洲乱码精品一二三四区日韩在线| 91蝌蚪视频在线观看| 午夜精品福利影院| 久久久久久久久综合| 国产99对白在线播放| 国产精品不卡在线| 精品久久久久久中文字幕2017| 欧美性生活一级片| 久久久在线观看| wwwxxxx国产| 亚洲精品成人精品456| 91aaa精品| 91精品天堂福利在线观看| 国产美女精品视频免费观看| 香蕉视频911| 午夜精品久久久久久久久久| 久草视频福利在线| 韩日在线一区| 成人免费视频网站| 678在线观看视频| 欧美va亚洲va香蕉在线| 欧美激情国产精品免费| 国产成人超碰人人澡人人澡| 青青在线视频免费观看| 大片在线观看网站免费收看| 激情av在线播放| 欧美xxxx在线观看| 国产精久久久久久| 波多野洁衣一区| 91视频最新入口| 久久99精品久久久久久园产越南| 欧洲中文字幕国产精品| 精品电影在线| 欧美精品丝袜久久久中文字幕| 五月天婷婷丁香网| 国产乱码精品一区二区三| 麻豆一区二区三区在线观看| 最新国产精品精品视频| 2018日韩中文字幕| 国产毛片av在线| 制服丝袜亚洲网站| 久久久久成人精品无码| 99久久久精品| 中文字幕国内自拍| 亚洲一级淫片| 好看的日韩精品视频在线| 户外露出一区二区三区| 日韩小视频在线| 丰满大乳国产精品| 色婷婷综合久久久中文一区二区 | 国产精品吹潮在线观看| 成人亚洲综合天堂| 欧美成人综合网站| 黑人一级大毛片| 国产精品久久久久aaaa樱花| 风韵丰满熟妇啪啪区老熟熟女| 亚洲综合好骚| 在线观看欧美亚洲| 国产在线播放精品| 国产精品视频在线观看| 日韩av毛片| 国产亚洲美女精品久久久| 99国产在线播放| 欧美视频一二三| 国产探花在线视频| av成人动漫在线观看| 欧美伦理片在线观看| 韩国av一区| 亚洲成人精品电影在线观看| 午夜精品在线| 国产精品视频一区二区三区四| 1stkiss在线漫画| 日韩免费电影| 亚洲精品美女在线| 91国在线视频| 色综合亚洲欧洲| 久久精品视频免费在线观看| 久久久久久麻豆| 国产免费a级片| 久久国产夜色精品鲁鲁99| 无码aⅴ精品一区二区三区浪潮| 婷婷六月综合| 日日骚一区二区网站| 九九热播视频在线精品6| 国产人妖伪娘一区91| 丝袜老师在线| 欧美黑人xxxx| 国产黄色在线网站| 一区二区三区高清国产| 三级在线观看| 精品电影一区二区三区| 国产露脸91国语对白| 欧美网站大全在线观看| 欧美啪啪小视频| 亚洲一二三四区不卡| 午夜爽爽爽男女免费观看| 欧美激情在线免费观看| 性欧美丰满熟妇xxxx性仙踪林| 不卡视频免费播放| 免费黄视频在线观看| 国产资源精品在线观看| 在线观看国产一级片| 日韩和欧美一区二区| 欧美aⅴ在线观看| 99pao成人国产永久免费视频| wwwwww欧美| 欧美在线91| 无码人妻精品一区二区三区99v| 欧美xxxx中国| 亚洲无玛一区| 91日韩在线| 在线观看亚洲视频啊啊啊啊| 日韩精品中文字幕第1页| 日本欧美色综合网站免费| 亚洲69av| 欧美另类一区| 国内精品视频在线观看| 日本在线观看不卡| 狠狠做六月爱婷婷综合aⅴ| 蜜桃臀一区二区三区| 一区二区三区视频免费观看| 久久精品国产第一区二区三区最新章节| 成人春色在线观看免费网站| 亚洲xxx自由成熟| 亚洲精品v亚洲精品v日韩精品| 国产精品.com| 另类在线视频| 日本亚洲自拍| 四虎成人av| 日本一道在线观看| 国内久久精品| 久久精品国产精品亚洲色婷婷| 亚洲在线成人| 在线观看的毛片| 国产在线精品一区在线观看麻豆| 日本黄色大片在线观看| 成人手机在线视频| 自拍视频一区二区| 国产欧美一区二区三区鸳鸯浴 | 韩国一区二区三区四区| 成人av在线影院| 瑟瑟视频在线观看| 国产精品护士白丝一区av| 看片网站在线观看| 狠狠色狠狠色综合日日小说| 日韩免费av网站| 欧美久久久久久蜜桃| 亚洲国产剧情在线观看| 日韩av在线免费播放| 国产高清在线看| 欧美成人在线免费视频| 涩涩涩在线视频| 国产日韩欧美中文在线播放| 一区二区三区视频免费视频观看网站| 国产偷久久久精品专区| 精品日本12videosex| 色爽爽爽爽爽爽爽爽| 国产午夜精品一区二区三区欧美| 91n.com在线观看| 国产a级毛片一区| 一区二区三区四区免费| 亚洲欧美日韩一区二区三区在线观看| 国产午夜小视频| 欧美特级限制片免费在线观看| 国产黄色美女视频| 亚洲图片在区色| 日韩精品分区| 国产精品久久久久久久美男| aaa国产精品视频| 无遮挡亚洲一区| 最新亚洲视频| 久久久久久综合网| 久久久一区二区三区| 久久久久亚洲AV成人| 色婷婷激情综合| www.亚洲天堂.com| 色黄久久久久久| 亚洲人成午夜免电影费观看| 91高跟黑色丝袜呻吟在线观看| 久久不见久久见中文字幕免费| 成年在线观看视频| 久久aⅴ国产欧美74aaa| 日本黄色动态图| 亚洲精品成人a在线观看| 久久久久久av无码免费看大片| 精品国产一区二区在线观看| 日本中文在线| 国产va免费精品高清在线观看| 一区二区三区四区精品视频| 国产91av视频在线观看| 日韩和欧美一区二区三区| 国产伦精品一区三区精东| 亚洲少妇30p| 在线免费观看一级片| 亚洲欧洲激情在线| 538在线视频| 国产精品swag| 欧美激情自拍| 色噜噜狠狠一区二区三区狼国成人| 久久精品夜色噜噜亚洲aⅴ| 1级黄色大片儿| 日韩精品影音先锋| av毛片在线免费看| 95av在线视频| 国产精品传媒精东影业在线| 日韩av卡一卡二| 中国色在线观看另类| 久久精品国产亚洲av麻豆蜜芽| 亚洲美女免费精品视频在线观看| 97超碰在线免费| 国产伦精品一区二区三区视频免费| 欧美久久99| 国产又黄又嫩又滑又白| 亚洲日穴在线视频| 国产乱人乱偷精品视频| 久久亚洲成人精品| 国产免费区一区二区三视频免费| 一区二区成人国产精品| 久久成人免费日本黄色| 国精品人伦一区二区三区蜜桃| 欧美日韩一区二区在线观看 | 中文字幕一区二区三区蜜月 | 亚洲精品乱码久久久久久金桔影视 | 一区二区三区91| 亚洲欧美高清视频| 国外成人免费在线播放| 欧美一区二区三区红桃小说| 欧美 日韩 激情| 国产婷婷一区二区| 老熟妇一区二区三区啪啪| 日韩在线免费av| 精品视频在线观看网站| 久久99久久99精品| 99精品视频中文字幕| 一区二区三区在线观看av| 亚洲色图第一页| 亚洲热av色在线播放| 国产又粗又猛又爽又黄的网站| 成人高清视频在线| 久久久免费高清视频| 中文字幕欧美日韩在线| 不卡精品视频| 国产在线播放观看| 欧美激情在线一区二区| av免费观看网址| 国产91精品久久久久久久| av在线不卡免费观看| 国产黄色一区二区三区| 同产精品九九九| www.亚洲免费| www.久久艹| 久久一二三四| 日本a级片视频| 日韩精品免费综合视频在线播放| 欧美影视资讯| 日韩精品一区二区三区四| 2023国产一二三区日本精品2022| 亚洲视频一区在线播放| 欧美激情小视频| 国产欧美一区| 国产精品欧美性爱| 一本大道av一区二区在线播放| 麻豆最新免费在线视频| 精品国产乱码久久久久久郑州公司| 日韩精品亚洲一区二区三区免费| 日韩欧美综合视频| 亚洲欧美日韩综合| 精品视频一区二区三区| 人妻无码视频一区二区三区| 亚洲综合色丁香婷婷六月图片| 国产资源在线播放| 99三级在线| 七七婷婷婷婷精品国产| 国产午夜小视频| 久久久久99精品久久久久|