当前位置: 首页 > news >正文

go语言map底层及扩容机制原理详解(下)

前言

上文对Go map的底层数据结构有所了解,并对其扩容机制的步骤进行简略的描述。本文将会详细地去解释Go map扩容机制的详细原理。

1. 触发扩容操作

在go语言中,当我们插入一个元素到hmap时,会有以下两种情况:

  1. 若元素存在,则更新元素的val
  2. 若元素不存在,则将该元素插入到map中。

此处的插入操作并不是简单的找到一个空余空间插入,而是在插入之前,要先判断map是否需要扩容以及是否正在进行扩容操作。
因为当map非常大的情况下,每次迁移大量的数据,会出现长时间的暂停。在go1.8版本以后,这个步骤采用来分批迁移的策略:即每次向map添加新元素或查找时,都会迁移一小部分元素,避免长时间的暂停。

// 如果我们达到了最大负载因子×容量的阈值,或者我们有太多的溢出桶,
// 并且我们还没有处于增长中,那么开始增长。
if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {hashGrow(t, h)goto again 
}// growing 报告 h 是否正在扩容。扩容可能是到相同的大小或更大。
// 通过判断oldbuckets是否为nil来判断是否扩容完成
func (h *hmap) growing() bool {return h.oldbuckets != nil
}

因此,当进行查询或插入操作时,若map的元素数量超过了负载因子×容量的阈值或太多的桶溢出没有正在发生扩容操作,就会触发扩容。

2. 触发扩容的条件

上文我们分析了触发扩容操作需要达到负载因子和容量乘积的阈值或桶溢出过多。那么它的底层到底是如何具体进行判断实现的呢?
Go的底层主要内置了两个函数来判断,分别是overLoadFactortooManyOverflowBuckets1:

const (// 一个桶可以容纳的键/元素对的最大数量。bucketCntBits = 3bucketCnt     = 1 << bucketCntBits // 相当于2^3 = 8// 触发增长的桶的最大平均负载是6.5。// 表示为 loadFactorNum/loadFactorDen,以允许使用整数数学运算。loadFactorNum = 13loadFactorDen = 2
)
// bucketShift 返回 1<<b,为了优化代码生成。
func bucketShift(b uint8) uintptr {// 通过掩码处理移位数量,可以省略溢出检查。return uintptr(1) << (b & (goarch.PtrSize*8 - 1))
}// overLoadFactor 报告将 count 个项放置在 1<<B 个桶中是否超过负载因子。
func overLoadFactor(count int, B uint8) bool {// 如果 count 大于每个桶能容纳的元素数量(bucketCnt),并且// count 大于负载因子允许的最大元素数量(loadFactorNum*(bucketShift(B)/loadFactorDen)),// 则返回 true,表示超过负载因子。return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
}// tooManyOverflowBuckets 报告对于具有 1<<B 个桶的 map 而言,noverflow 个溢出桶是否太多。
// 注意这些溢出桶大部分必须在稀疏使用中;
// 如果使用密集,那么我们已经触发了常规的 map 增长。
func tooManyOverflowBuckets(noverflow uint16, B uint8) bool {// 如果阈值过低,我们会做额外的工作。// 如果阈值过高,那么增长和收缩的 map 可以保留大量未使用的内存。// “太多”意味着(大约)与常规桶一样多的溢出桶。// 有关更多详细信息,请参阅 incrnoverflow。if B > 15 {B = 15}// 编译器在这里看不到 B < 16;掩蔽 B 以生成更短的移位代码。return noverflow >= uint16(1)<<(B&15)
}

正在速更…

相关文章:

go语言map底层及扩容机制原理详解(下)

前言 上文对Go map的底层数据结构有所了解&#xff0c;并对其扩容机制的步骤进行简略的描述。本文将会详细地去解释Go map扩容机制的详细原理。 1. 触发扩容操作 在go语言中&#xff0c;当我们插入一个元素到hmap时&#xff0c;会有以下两种情况&#xff1a; 若元素存在&…...

网络协议二 : 使用Cisco Packet Traceer工具模拟网络环境,集线器,网桥,交换机,路由器,IP,同一网段

1. 安装 Cisco Packet Tracer baidu 网盘地址&#xff0c;感谢大神分享 安装&#xff0c;破解&#xff0c;中文化&#xff0c;都有说明&#xff0c;建议使用7.x的那个版本&#xff0c;感觉比8.x的翻译要完整一点 https://pan.baidu.com/s/18iWBOfhJJRhqgQqdNQcfMQ?pwddcch#…...

Aria2 任意文件写入漏洞

目录 Aria2介绍漏洞描述漏洞复现 Aria2介绍 Aria2是一个在命令行下运行&#xff0c;多协议&#xff0c;多来源下载工具&#xff08;HTTP / HTTPS&#xff0c;FTP&#xff0c;BitTorrent&#xff0c;Metalink&#xff09;&#xff0c;内建XML-RPC用户界面。Aria提供RPC服务器&a…...

成为git砖家(4): git status 命令简介

1. untracked 和 tracked 状态 Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot, as well as any newly staged files; they can be unmodified, modified, o…...

2-48 基于matlab的EM算法聚类可视化程序

基于matlab的EM算法聚类可视化程序&#xff0c;通过期望最大化算法&#xff08;EM&#xff09;优化类别间距&#xff0c;使得类别间距最大、类内间距最小。输出聚类前后结果及收敛曲线。程序已调通&#xff0c;可直接运行。 2-48 期望最大化算法&#xff08;EM&#xff09; 聚类…...

k8s 使用技巧

文章目录 kubectlkubectl 自动补全kubectl 上下文和配置打印当前使用 API 调用过程生成yaml模板强制删除 Pod&#xff08;即使处于Terminating&#xff09; kubectl kubectl 自动补全 source < (kubectl completion bash) # setup autocomplete in bash, bash-completion …...

学习笔记-系统框图传递函数公式推导

目录 *待了解 现代控制理论和自动控制理论区别 自动控制系统的组成 信号流图 1、系统框图 1.1、信号线、分支点、相加点 1.2、系统各环节间的连接 1.3、 相加点和分支点的等效移动&#xff08;比较点、引出点&#xff09; 2、反馈连接公式推导 2.1、前向通路传递函数…...

C++ - 基于多设计模式下的同步异步⽇志系统

1.项目介绍 项⽬介绍 本项⽬主要实现⼀个⽇志系统&#xff0c; 其主要⽀持以下功能: • ⽀持多级别⽇志消息 • ⽀持同步⽇志和异步⽇志 • ⽀持可靠写⼊⽇志到控制台、⽂件以及滚动⽂件中 • ⽀持多线程程序并发写⽇志 • ⽀持扩展不同的⽇志落地⽬标地 2.开发环境 • Cent…...

git 相关内容

...

ElasticSearch(es)倒排索引

目录 一、ElasticSearch 二、倒排索引 1. 正向索引 2. 倒排索引 具体细节 1. 文档分析 2. 索引构建 3. 索引存储 4. 词条编码 5. 索引优化 6. 查询处理 示例 总结 3. 正向和倒排 三、总结 倒排索引的基本概念 为什么倒排索引快 一、ElasticSearch Elasticsear…...

【自然语言处理】概论(一):自然语言处理概要

1.1 概论&#xff1a;&#xff08;一&#xff09;自然语言处理概要 知识点 自然语言的定义&#xff1a;人类交流使用的&#xff0c;包括口语和书面语的信息交流方式。AI的终极目标&#xff1a;使计算机具备理解&#xff08;听、读&#xff09;和生成&#xff08;说、写&#…...

flask 开始

# 导入flask类 from flask import Flask,request,render_template # 使用flask类来创建一个app对象 # __name__ 代表当前app.py 这个模块 app Flask(__name__) # 创建一个路由和视图函数的映射 url http://127.0.0.1:5000/ app.route("/") def hello_word():return …...

仕考网:公务员可以报考军队文职吗?

公务员可以报考军队文职考试&#xff0c;但是需要满足前提条件。 对于已经与国家、地方的用人单位建立劳动关系的社会人才&#xff0c;在获得当前用人单位的许可后才可以申请报考。 在面试过程中&#xff0c;考生必须出示一份由其用人单位出具的且加盖公章的同意报考证明。一…...

Java整理22

1、动态sql 多条件查询 .xml配置文件中sql语句书写<select id"getEmpByCondition",resultType"Emp">select * from t_emp where <if test"empName ! null and empName! ">empName#{empName}</if><if test"age ! nul…...

leetcode 408周赛 3234. 统计 1 显著的字符串的数量

3234. 统计 1 显著的字符串的数量 题目描述 给你一个二进制字符串 s。 请你统计并返回其中 1 显著 的子字符串的数量。 如果字符串中 1 的数量 大于或等于 0 的数量的 平方&#xff0c;则认为该字符串是一个 1 显著 的字符串 。 思路 一个很显然的思路是&#xff0c;我们…...

容器对比虚拟机有哪些不足?

引言 在当今的云计算和微服务架构中&#xff0c;容器技术已成为不可或缺的一部分。它以其轻量级、高效和快速部署的特性&#xff0c;赢得了广大开发者和运维人员的青睐。然而&#xff0c;正如任何技术都有其两面性&#xff0c;容器技术也不例外。本文将对容器技术在安全性、隔离…...

C# 归并排序

栏目总目录 概念 归并排序是一种分而治之的排序算法。它将一个大数组分成两个小数组&#xff0c;递归地对这两个小数组进行排序&#xff0c;然后将排序好的小数组合并成一个有序的大数组。这个过程一直递归进行&#xff0c;直到数组被拆分成只有一个元素的数组&#xff08;自然…...

【请求代理】springboot单机服务基于过滤器Filter实现第三方服务器接口请求代理功能

springboot单机服务基于过滤器Filter实现第三方服务器接口请求代理功能 一、前言二、解决思路三、基于gateway实现四、基于过滤器Filter实现五、问题总结 **注&#xff1a;本文源码获取或者更多资料&#xff0c;关注公众号&#xff1a;技术闲人**一、前言 在项目开发时会遇到w…...

.NET Core异步编程与多线程解析:提升性能与响应能力的关键技术

在.NET Core中&#xff0c;异步编程和多线程是构建高性能应用程序的核心技能。理解这两个概念不仅可以提升应用程序的响应能力&#xff0c;还能优化资源使用。本文将深入剖析异步编程和多线程的关键知识点&#xff0c;提供代码示例&#xff0c;并附上步骤以帮助理解。 1. 异步…...

Photoshop(PS) 抠图简单教程

目录 快速选择 魔棒 钢笔 橡皮擦 蒙版 通道 小结 可以发现&#xff0c;ps逐渐成为必备基础的办公软件。本文让ps新手轻松学会抠图。 快速选择 在抠图之前&#xff0c;先了解下选区的概念。ps中大多数的抠图操作都是基于选区的&#xff0c;先选区再Ctrl J提取选区。而快…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...