前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang Map

Golang Map

原创
作者头像
Arata
发布2022-10-25 20:14:11
2110
发布2022-10-25 20:14:11
举报
文章被收录于专栏:自我提升自我提升

源码位置

runtime/map.go

底层结构

代码语言:txt
复制
type hmap struct {
    count int // 元素个数
    flags uint8
    B uint8 // 桶数量, 2^B个
    noverflow uint16 // 使用的溢出桶数量
    hash0 uint32 // 哈希种子

    buckets unsafe.Pointer // 桶指针
    oldbuckets unsafe.Pointer // 旧桶指针,只在扩容时非空
    nevacuate uintptr // 记录扩容进度,记录下一个迁移的桶编号

    extra *mapextra // 溢出桶信息
}

type bmap struct {
    tophash [8]uint8 // 存哈希值高8位
}

实际bmap后会紧跟8个key和8个value以及溢出桶指针,即类似以下结构

代码语言:txt
复制
type bmap struct {
    tophash [8]uint8 // 存哈希值高8位
    keys [8]KeyType
    values [8]ValueType
    overflow *bmap
}

示例图

image.png
image.png

注:实际h、k、v并不一定对齐,取决于map的key和value的类型

初始化流程

image.png
image.png

B>=4的情况会提前分配2^(B-4)个溢出桶

扩容

负载因子:元素数量/桶数量,即count/2^B

两种扩容情况,一种是增量扩容,一种是等量扩容

等量扩容是在大量删除key的情况下,重新分配k、v排列,减少空间、及溢出桶的使用

扩容规则:

1.翻倍扩容

count/2^B > 6.5,触发翻倍扩容,B++

2.等量扩容

B <= 15的情况,count >=2^B即触发等量扩容

B > 15的情况,count >= 2^15即触发等量扩容

渐进式扩容:扩容并非一次性完成所有桶迁移,而是在map操作时分多次完成迁移,防止性能瞬时抖动

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码位置
  • 底层结构
    • 示例图
    • 初始化流程
    • 扩容
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档