最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang中map縮容的實現(xiàn)

 更新時間:2025年03月04日 11:24:00   作者:李若盛開  
本文主要介紹了Go語言中map的擴(kuò)縮容機(jī)制,包括grow和hashGrow方法的處理,具有一定的參考價值,感興趣的可以了解一下

基本分析

在 Go 底層源碼 src/runtime/map.go 中,擴(kuò)縮容的處理方法是 grow 為前綴的方法來處理的。

其中擴(kuò)縮容涉及到的是插入元素的操作,對應(yīng) mapassign 方法:

func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
  ...
 if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
  hashGrow(t, h)
  goto again
 }
  ...
}
func (h *hmap) growing() bool {
 return h.oldbuckets != nil
}
func overLoadFactor(count int, B uint8) bool {
 return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
}
func tooManyOverflowBuckets(noverflow uint16, B uint8) bool {
 if B > 15 {
  B = 15
 }
 return noverflow >= uint16(1)<<(B&15)
} 

核心看到針對擴(kuò)縮容的判斷邏輯:

當(dāng)前沒有在擴(kuò)容:條件為 oldbuckets 不為 nil。

是否可以進(jìn)行擴(kuò)容:條件為 hmap.count> hash 桶數(shù)量 (2^B)*6.5。其中 hmap.count 指的是map 的數(shù)據(jù)數(shù)目, 2^B 僅指 hash 數(shù)組的大小,不包含溢出桶。

是否可以進(jìn)行縮容:條件為溢出桶(noverflow)的數(shù)量 >= 32768(1<<15)。

可以關(guān)注到,無論是擴(kuò)容還是縮容,其都是由 hashGrow 方法進(jìn)行處理:

 func hashGrow(t *maptype, h *hmap) {
 bigger := uint8(1)
 if !overLoadFactor(h.count+1, h.B) {
  bigger = 0
  h.flags |= sameSizeGrow
 }
  ...
}

若是擴(kuò)容,則 bigger 為 1,也就是 B+1。代表 hash 表容量擴(kuò)大 1 倍。不滿足就是縮容,也就是 hash 表容量不變。

可以得出結(jié)論:map 的擴(kuò)縮容的主要區(qū)別在于 hmap.B 的容量大小改變。而縮容由于 hmap.B 壓根沒變,內(nèi)存空間的占用也是沒有變化的。

帶來的隱患

這種方式其實是存在運行隱患的,也就是導(dǎo)致在刪除元素時,并不會釋放內(nèi)存,使得分配的總內(nèi)存不斷增加。如果一個不小心,拿 map 來做大 key/value 的存儲,也不注意管理,很容易就內(nèi)存爆了。

也就是 Go 語言的 map 目前實現(xiàn)的是 “偽縮容”,僅針對溢出桶過多的情況。若是觸發(fā)縮容,hash 數(shù)組的占用的內(nèi)存大小不變(等量擴(kuò)容)。

若要實現(xiàn) ”真縮容“,Go Contributor @josharian 表示目前唯一可用的解決方法是:創(chuàng)建一個新的 map 并從舊的 map 中復(fù)制元素。

示例如下:

old := make(map[int]int, 9999999)
new := make(map[int]int, len(old))
for k, v := range old {
    new[k] = v
}
old = new
...

為什么不支持縮容

下述內(nèi)容會主要基于如下兩個 issues 和 proposal 來分析:

《runtime: shrink map as elements are deleted[1]》
《proposal: runtime: add way to clear and reuse a map's working storage[2]》

目前 map 的縮容處理起來比較棘手,最早的 issues 是 2016 年提出的,也有人提過一些提案,但都因為種種原因被拒絕了。

簡單來講,就是沒有找到一個很好的方法實現(xiàn),存在明確的實現(xiàn)成本問題,沒辦法很方便的 ”告訴“ Go 運行時,我要:

  • 記得保留存儲空間,我要立即重用 map。
  • 趕緊釋放存儲空間,map 從現(xiàn)在開始會小很多。

抽象來看癥結(jié)是:需要保證增長結(jié)果在下一個開始之前完成,此處的增長指的是 ”從小到大,從一個大小到相同大小,從大到小“ 的復(fù)雜過程。

這屬于一個多重 case,從而導(dǎo)致也就一直拖著,慢慢想。

到此這篇關(guān)于Golang中map縮容的實現(xiàn)的文章就介紹到這了,更多相關(guān)Golang map縮容 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go函數(shù)的使用示例教程

    Go函數(shù)的使用示例教程

    這篇文章主要介紹了Go函數(shù)的使用示例,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • Go語言極簡入門之語法、并發(fā)及避坑全攻略

    Go語言極簡入門之語法、并發(fā)及避坑全攻略

    Go是由谷歌支持的開源編程語言,屬于編譯型語言,對并發(fā)編程有較好的支持,這篇文章主要介紹了Go語言極簡入門之語法、并發(fā)及避坑的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-06-06
  • 如何判斷Golang接口是否實現(xiàn)的操作

    如何判斷Golang接口是否實現(xiàn)的操作

    這篇文章主要介紹了如何判斷Golang接口是否實現(xiàn)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言omitempty選項的實現(xiàn)

    Go語言omitempty選項的實現(xiàn)

    本文主要介紹了Go語言omitempty選項的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • go語言實現(xiàn)字符串與其它類型轉(zhuǎn)換(strconv包)

    go語言實現(xiàn)字符串與其它類型轉(zhuǎn)換(strconv包)

    strconv包是Go語言標(biāo)準(zhǔn)庫的一部分,主要提供字符串與基本數(shù)據(jù)類型之間的轉(zhuǎn)換功能,使用strconv包可以方便地在不同類型之間進(jìn)行轉(zhuǎn)換,滿足日常編程中的需求,感興趣的可以了解一下
    2024-10-10
  • go語言中time包的各種函數(shù)總結(jié)

    go語言中time包的各種函數(shù)總結(jié)

    時間和日期是我們編程中經(jīng)常會用到的,下面這篇文章主要給大家介紹了關(guān)于go語言中time包的各種函數(shù)總結(jié)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • Go語言中g(shù)PRC的使用

    Go語言中g(shù)PRC的使用

    本文主要介紹了Go語言中g(shù)PRC的使用,包括Protobuf定義服務(wù)接口、HTTP/2協(xié)議與性能優(yōu)勢,以及流模式和發(fā)布-訂閱系統(tǒng)的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2025-07-07
  • Go?連接?MySQL之?MySQL?預(yù)處理詳解

    Go?連接?MySQL之?MySQL?預(yù)處理詳解

    Go語言提供了豐富的庫和工具,可以方便地連接MySQL數(shù)據(jù)庫。MySQL預(yù)處理是一種提高數(shù)據(jù)庫操作效率和安全性的技術(shù)。Go語言中的第三方庫提供了MySQL預(yù)處理的支持,通過使用預(yù)處理語句,可以避免SQL注入攻擊,并且可以提高數(shù)據(jù)庫操作的效率。
    2023-06-06
  • Go中的gRPC入門教程詳解

    Go中的gRPC入門教程詳解

    本文詳細(xì)講解了Go中的gRPC入門教程,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • Go語言net包RPC遠(yuǎn)程調(diào)用三種方式http與json-rpc及tcp

    Go語言net包RPC遠(yuǎn)程調(diào)用三種方式http與json-rpc及tcp

    這篇文章主要為大家介紹了Go語言net包RPC遠(yuǎn)程調(diào)用三種方式分別使用http與json-rpc及tcp的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11

最新評論

庆元县| 阜新市| 瑞金市| 舞钢市| 积石山| 蕲春县| 沧州市| 治县。| 淳安县| 象州县| 道真| 卢龙县| 潮安县| 开远市| 孙吴县| 富裕县| 崇明县| 双江| 三门县| 新民市| 肇州县| 额济纳旗| 五莲县| 郸城县| 富锦市| 东兰县| 潜山县| 潼关县| 旌德县| 兴国县| 察雅县| 房产| 齐河县| 类乌齐县| 泰宁县| 广水市| 宾阳县| 内黄县| 嵊泗县| 集安市| 浮山县|