精品欧美一区二区三区在线观看 _久久久久国色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)

亚洲免费中文字幕| 亚洲综合免费观看高清完整版在线| 久久久久国产精品免费| japanese在线观看| 欧美电影免费观看高清完整| 国产三级久久久| 91在线网站视频| 日韩av大片在线观看| 成人婷婷网色偷偷亚洲男人的天堂| 欧美精品v日韩精品v韩国精品v| 国产精品视频一二三四区| 香蕉av在线播放| 日本午夜一区二区| 欧美精品18videos性欧美| 亚洲做受高潮无遮挡| 亚洲人体在线| 欧美性猛交xxxx| 男人的天堂视频在线| 男人av在线| 国产精选一区二区三区| 66m—66摸成人免费视频| 欧美成人短视频| 久久这里只有精品一区二区| 欧美三级资源在线| 国产视频九色蝌蚪| 羞羞视频在线观看免费| 国产欧美日韩不卡免费| 精品免费视频123区| 91亚洲国产成人久久精品麻豆| 99热免费精品| 久久69精品久久久久久国产越南| 影音先锋男人在线| 亚洲va久久| 精品久久五月天| 天美一区二区三区| 成人免费黄色| 日本韩国欧美在线| 欧美 日韩 国产在线观看| av网址在线看| 国产精品免费网站在线观看| 欧美日韩另类丝袜其他| 天天舔天天干天天操| 国产成人精品免费视频网站| 国产在线精品成人一区二区三区| 69亚洲精品久久久蜜桃小说 | 亚洲国产又黄又爽女人高潮的| 亚洲第一天堂久久| 久久亚洲精品中文字幕| 日本电影亚洲天堂一区| 少妇高清精品毛片在线视频 | 亚洲国产一区二区三区在线播放| 国产亚洲精品美女| 美女脱光内衣内裤| 亚洲最大在线| 亚洲丝袜在线视频| 欧美高清性xxxx| 婷婷成人在线| 亚洲欧美日韩天堂一区二区| 免费a级黄色片| 杨幂一区二区三区免费看视频| 亚洲美女久久久| 99久久久久久久久久| 日韩手机在线| 亚洲深夜福利视频| 我想看黄色大片| 久久国产电影| 久久躁狠狠躁夜夜爽| 四虎永久免费在线| 亚洲无毛电影| 亚洲 日韩 国产第一| 国产精品suv一区二区三区| 国产亚洲成人一区| 国产精品成人免费电影| 中文字幕一区二区三区四区视频| 久久精品久久久精品美女| 91九色国产社区在线观看| 精品国产伦一区二区三区| 粉嫩嫩av羞羞动漫久久久| 国产精品国产三级欧美二区| 熟妇人妻av无码一区二区三区| 91麻豆国产精品久久| 青娱乐一区二区| 黄色在线视频网站| 亚洲成人在线免费| 日本中文字幕片| 一区二区三区| 亚洲第一网站免费视频| 美女脱光内衣内裤| 综合激情婷婷| 热re99久久精品国产66热| 中文字幕乱码视频| 成人综合激情网| 青青草成人网| 欧美6一10sex性hd| 一本久久精品一区二区| 特级西西444www| 美女视频免费精品| 日韩一区二区在线视频| 精品人妻在线播放| 视频一区二区欧美| 97人人模人人爽人人喊38tv| 午夜在线视频观看| 亚洲精选免费视频| 久久综合久久色| 亚洲国产一区二区三区网站| 亚洲精品一区中文| 久久国产一级片| 日本视频免费一区| 精品午夜一区二区三区| 色多多视频在线观看| 亚洲成人你懂的| 热久久久久久久久| 九九热线有精品视频99| 欧美高清第一页| 中文字幕黄色av| 久久综合网色—综合色88| 日韩不卡一二区| 国产激情欧美| 亚洲人高潮女人毛茸茸| 青娱乐国产在线| 免费在线观看一区二区三区| 国产一区二区三区色淫影院 | 久久人人爽人人爽人人片av高请| 亚洲免费视频二区| 久久天天做天天爱综合色| 隔壁人妻偷人bd中字| 亚洲人体在线| 日韩中文字幕网站| 波多野结衣影片| 91免费视频网址| av在线观看地址| 日本综合精品一区| www国产91| 亚洲天堂自拍偷拍| 国产三级精品视频| 成人中文字幕av| 杨幂一区二区三区免费看视频| 国模精品视频一区二区三区| jlzzjlzzjlzz亚洲人| 国产精品电影一区二区三区| 成人免费xxxxx在线视频| 欧美精品中文字幕亚洲专区| 久久久在线视频| 成人免费视频国产| 一区二区三区日本| 性一交一黄一片| 欧美另类综合| 91文字幕巨乱亚洲香蕉| 亚洲性图自拍| 日韩美女一区二区三区| 欧美精品乱码视频一二专区| 国产精品自在欧美一区| 日韩中文在线字幕| 911精品国产| 97国产精品视频人人做人人爱| 精品人妻伦一区二区三区久久 | 日本中文字幕在线免费观看| 成人午夜电影小说| 777av视频| 亚洲国产精品嫩草影院久久av| 欧美中文字幕在线播放| 国外av在线| 欧美少妇xxx| 日韩欧美国产成人精品免费| 国产一区二区剧情av在线| 可以免费看的黄色网址| 久久av偷拍| 久久久久亚洲精品成人网小说| 神马午夜在线观看| 色系网站成人免费| 亚洲熟女少妇一区二区| 国内成+人亚洲+欧美+综合在线| mm131午夜| 国产图片一区| 97精品在线视频| 高清在线观看av| 日韩视频在线你懂得| 欧美一二三区视频| 国产三级精品视频| 激情五月婷婷基地| 伊人成年综合电影网| 欧美在线视频二区| av国产精品| 91干在线观看| 九七电影韩国女主播在线观看| 欧美v亚洲v综合ⅴ国产v| 超碰超碰超碰超碰| 综合精品久久久| 日本不卡视频一区| 人人精品人人爱| 日韩国产成人无码av毛片| 蜜桃一区二区三区| 91麻豆蜜桃| 欧美电影网站| 久久久久久亚洲精品不卡| 国产福利电影在线| 精品国产第一区二区三区观看体验| 国产免费av一区| 亚洲乱码一区二区三区在线观看| 好吊日免费视频| 国产精品一区二区三区乱码| 国内外成人免费激情视频| 亚洲国产一区二区在线观看| 欧美精品123| 日韩中文字幕一区二区高清99| 日本久久91av| 国产美女情趣调教h一区二区| 国产亚洲精品美女| 熟妇人妻中文av无码| 欧美日本精品一区二区三区| 日韩一区二区视频在线| 伊人色综合久久天天人手人婷| 久久久久久久久久久久| 成人激情小说乱人伦| 日本人69视频| 日韩国产欧美在线播放| 日韩a∨精品日韩在线观看| 999国产精品| 日本一区二区精品视频| 国产精品美女在线观看直播| 亚洲一区二区久久久久久久| 经典三级一区二区| 国产91精品视频在线观看| 日本无删减在线| 久久久久999| 在线免费av电影| 亚洲午夜精品久久久久久久久久久久| 噜噜噜久久,亚洲精品国产品| 337p亚洲精品色噜噜狠狠| 青青国产在线视频| 欧美性xxxx在线播放| 日韩欧美一级视频| 亚洲电影一区二区三区| 欧美激情一区二区视频| 亚洲精品大片www| 日韩欧美综合视频| 亚洲摸摸操操av| 一区二区成人免费视频| 成人免费在线视频| 国产精品久久久视频| 日本一区二区三区在线观看| 国产特黄级aaaaa片免| 成人午夜激情在线| 日本69式三人交| jlzzjlzz国产精品久久| 亚洲啪av永久无码精品放毛片 | 在线精品视频一区二区| 欧美一级淫片免费视频黄| 欧美午夜久久久| 久久精品无码av| 色琪琪一区二区三区亚洲区| 国产精品视频一区在线观看| 欧美日韩中文字幕在线| 免费av网站在线| 在线欧美一区二区| 中文字幕91爱爱| 欧美精品tushy高清| 国产成人精品一区二区无码呦| 欧美一级精品在线| 少妇人妻一区二区| 日韩精品免费在线视频| 久草在线免费福利资源| 中文字幕免费精品一区高清| av大全在线免费看| 美女撒尿一区二区三区| 日本片在线观看| 69国产精品成人在线播放| 欧洲亚洲两性| 成人国内精品久久久久一区| 亚洲国产中文在线| 韩国成人动漫在线观看| 国产探花一区| 中文字幕av久久| 亚洲第一黄色| 男女无套免费视频网站动漫| 久久国产夜色精品鲁鲁99| 性生活一级大片| 99精品久久免费看蜜臀剧情介绍| 人妻少妇无码精品视频区| 日韩一区欧美一区| 国产成人无码精品亚洲| 欧美综合天天夜夜久久| 国产夫绿帽单男3p精品视频| 精品视频一区在线视频| 四虎久久免费| 97在线观看免费| 欧美综合社区国产| 国内一区在线| 99九九热只有国产精品| a级黄色小视频| 日本欧美一区二区三区乱码 | 成人爽a毛片免费啪啪红桃视频| 美女视频久久| 在线成人激情| 国产天堂在线播放| 粉嫩aⅴ一区二区三区四区| 日本性高潮视频| 亚洲第一激情av| 在线观看黄色国产| 日韩成人性视频| www免费在线观看| 国产精品成人一区二区| 97色成人综合网站| 亚洲五月六月| 亚洲综合丁香| 亚洲AV成人精品| 中文字幕av在线一区二区三区| 久久综合成人网| 在线播放中文一区| 精品成人一区二区三区免费视频| 欧美高跟鞋交xxxxhd| 91另类视频| 欧美日韩电影一区二区三区| 欧美视频二区| 91插插插影院| 国产精品色噜噜| 国产伦精品一区二区三区视频我 | 经典三级在线| 午夜精品久久久99热福利| 99精品美女视频在线观看热舞| 欧美在线一区二区三区四区| 极品少妇一区二区三区| 在线视频日韩欧美| 国产精品成人午夜| 国产精品第6页| 亚洲欧美日韩一区在线| 美女视频在线免费| 国产精品一区二区三区在线观 | 精品国产影院| 妺妺窝人体色www看人体| 久久精品国产色蜜蜜麻豆| av黄色在线免费观看| 狠狠躁夜夜躁人人爽超碰91| 黄频网站在线观看| 欧美国产日韩一区二区在线观看| 在线视频成人| 熟女熟妇伦久久影院毛片一区二区| 日韩av一区二区在线影视| 免费一级做a爰片久久毛片潮| 欧美日韩国产在线看| 五月婷婷狠狠干| 欧美一区第一页| 外国成人在线视频| www.com毛片| 久久九九全国免费| 精品一区二区无码| 一本色道久久88综合日韩精品| 综合在线影院| 亚洲激情电影在线| 久久国产夜色精品鲁鲁99| 小泽玛利亚一区| 日韩精品一区二区三区swag| 日韩伦理电影网站| 国产精品v欧美精品v日韩| 亚洲韩日在线| 中文字幕xxx| 欧美视频一区在线| 成人在线免费看片| 91精品天堂| 中日韩男男gay无套| 亚洲av无码一区二区三区人| 色婷婷亚洲一区二区三区| 97视频在线观看网站| 91美女片黄在线观| 在线免费高清一区二区三区| 国产精品一级黄片| 91久久精品日日躁夜夜躁欧美| av电影在线观看| 99re在线观看| 亚洲尤物影院| 亚洲av无一区二区三区| 日韩欧美国产1| 亚洲一级少妇| 亚洲在线播放电影| 大尺度一区二区| 天天干天天插天天射| 久久国产精品影视| 日韩欧美美女在线观看| 精品日韩久久久| 一区二区三区在线看| 五月婷婷综合久久| 国产在线高清精品| 亚洲日本成人| 日本高清黄色片| 亚洲国产精品系列| 91p九色成人| 九九爱精品视频| 国产精品久久看| 五月天婷婷社区| 成人免费看黄网站| 国产亚洲高清视频| 中国毛片直接看| 亚洲热线99精品视频| 视频一区视频二区欧美| 欧美黄色一级片视频| 亚洲精品国产第一综合99久久| 美女欧美视频在线观看免费| 亚洲最大成人网色| 日韩av一区二区三区| 亚洲免费激情视频|