iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >go语言扩容方法有哪些
  • 754
分享到

go语言扩容方法有哪些

2023-07-05 00:07:52 754人浏览 泡泡鱼
摘要

这篇文章主要介绍“Go语言扩容方法有哪些”,在日常操作中,相信很多人在go语言扩容方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言扩容方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧

这篇文章主要介绍“Go语言扩容方法有哪些”,在日常操作中,相信很多人在go语言扩容方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言扩容方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

go语言扩容方法有:1、Slice扩容,在使用append向Slice追加元素时,如果Slice空间不足,将会触发Slice扩容;2、Map扩容。触发Map扩容的条件有二个:1、负载因子大于6.5时,也即平均每个bucket存储的键值对达到6.5个;2、overflow数量大于2^15时,也即overflow数量超过32768时。

Slice扩容

触发

使用append向Slice追加元素时,如果Slice空间不足,将会触发Slice扩容

原理

扩容实际上是重新分配一块更大的内存,将原Slice数据拷贝进新Slice,然后返回新Slice,扩容后再将数据追加进去。

机制

V1.8之前:

扩容容量的选择遵循以下规则:

  • 如果原Slice容量小于1024,则新Slice容量将扩大为原来的2倍;

  • 如果原Slice容量大于等于1024,则新Slice容量将扩大为原来的1.25倍;

// 1.17及以前的版本中// old指切片的旧容量, cap指期望的新容量func growslice(old, cap int) int {    newcap := old    doublecap := newcap + newcap    // 如果期望容量大于旧容量的2倍,则直接使用期望容量作为最终容量    if cap > doublecap {        newcap = cap    } else {        // 如果旧容量小于1024,则直接翻倍        if old < 1024 {            newcap = doublecap        } else {            // 每次增长大约1.25倍            for 0 < newcap && newcap < cap {                newcap += newcap / 4            }            if newcap <= 0 {                newcap = cap            }        }    }    // 这里忽略了对齐操作    return newcap}

V1.8之后:

新扩容容量的选择遵循以下规则:(拥有更平滑的扩容系数)

  • 如果原Slice容量小于256,则新Slice容量将扩大为原来的2倍;

  • 如果原Slice容量大于等于256,则新Slice容量将扩大为原来的  新容量 = (原容量+3*256)/4

// 只关心扩容规则的简化版growslicefunc growslice(old, cap int) int {    newcap := old    doublecap := newcap + newcap    if cap > doublecap {        newcap = cap    } else {        const threshold = 256 // 不同点1        if old < threshold {            newcap = doublecap        } else {            for 0 < newcap && newcap < cap {                newcap += (newcap + 3*threshold) / 4 // 不同点2            }            if newcap <= 0 {                newcap = cap            }        }    }    return newcap}

Map扩容

触发扩容的条件有二个:

  • 负载因子 > 6.5时,也即平均每个bucket存储的键值对达到6.5个。增量扩容

  • overflow数量 > 2^15时,也即overflow数量超过32768时。等量扩容/重排

注意:创建溢出桶不属于扩容机制

增量扩容

  • 当负载因子过大时,新开辟buckets空间,bucket数量为之前的 2 倍

  • 新空间被buckets引用,之前的旧空间被oldbuckets引用

  • 之后逐渐将 oldbuckets中的数据 搬迁到 新开辟的 buckets空间中去

考虑到如果map存储了数以亿计的key-value,一次性搬迁将会造成比较大的延时,Go采用逐步搬迁策略,即每次访问map时都会触发一次搬迁,每次搬迁2个键值对当oldbuckets中的键值对全部搬迁完毕后,删除oldbuckets。

下图展示了包含一个bucket满载的map(为了描述方便,图中bucket省略了value区域):

go语言扩容方法有哪些

当前map存储了7个键值对,只有1个bucket。此时负载因子为7 > 6.5。再次插入数据时将会触发扩容操作,扩容之后再将新插入键写入新的bucket。注意,因为负载因子的触发,不是创建溢出桶

当第8个键值对插入时,将会触发扩容扩容后示意图如下:

go语言扩容方法有哪些

后续对map的访问操作会触发迁移,将oldbuckets中的键值对逐步的搬迁过来。

搬迁完成后的示意图如下:

go语言扩容方法有哪些

数据搬迁过程中原bucket中的键值对将存在于新bucket的前面,新插入的键值对将存在于新bucket的后面。

等量扩容/重排

所谓等量扩容,实际上并不是扩大容量,buckets数量不变,重新做一遍类似增量扩容的搬迁动作,把松散的键值对重新排列一次,以使bucket的使用率更高,进而保证更快的存取。
在极端场景下,比如不断地增删,而键值对正好集中在一小部分的bucket,这样会造成overflow的bucket数量增多,但负载因子又不高,从而无法执行增量搬迁的情况,如下图所示:

go语言扩容方法有哪些

上图可见,overflow的bucket中大部分是空的,访问效率会很差。此时进行一次等量扩容,即buckets数量不变,经过重新组织后overflow的bucket数量会减少,即节省了空间又会提高访问效率。

到此,关于“go语言扩容方法有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: go语言扩容方法有哪些

本文链接: https://www.lsjlt.com/news/348630.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • go语言扩容方法有哪些
    这篇文章主要介绍“go语言扩容方法有哪些”,在日常操作中,相信很多人在go语言扩容方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言扩容方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-05
  • Centos下lvm扩容有哪些方法
    这篇文章主要讲解了“Centos下lvm扩容有哪些方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Centos下lvm扩容有哪些方法”吧!因生产需要对/data目录进行扩容,由原来的90G...
    99+
    2023-06-10
  • go语言中的输出方法有哪些
    这篇文章主要介绍了go语言中的输出方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇go语言中的输出方法有哪些文章都会有所收获,下面我们一起来看看吧。输出方法:1、Print()函数,可输出到控制台(不接...
    99+
    2023-07-04
  • Go 语言中的容器类型有哪些?
    Go 语言是一门快速、简洁、高效的编程语言,它的发展在不断地推动着软件工程的进步。在 Go 语言中,容器类型是一个非常重要的概念,它们能够帮助我们更好地组织和管理数据。在本文中,我们将讨论 Go 语言中的容器类型,以及它们的特点和用法。 ...
    99+
    2023-07-02
    数据类型 编程算法 容器
  • go语言的基本语法有哪些
    Go语言的基本语法主要包括以下几个方面:1.包声明:每个Go程序都是由包组成的,使用关键字"package"来声明包名。2.引入包:...
    99+
    2023-09-21
    go语言
  • go语言结构体定义有哪些方法
    go语言结构体定义的方法有:1、直接定义结构体字段;2、使用嵌入结构体;3、定义带有方法的结构体;4、使用指针类型作为结构体字段;5、使用数组或切片作为结构体字段。在Go语言中,可以使用结构体来定义一组相关字段的集合,这些字段可以是基本数据...
    99+
    2023-12-12
    go语言 结构体
  • go语言性能优化的方法有哪些
    Go语言的性能优化方法如下: 使用并发:利用Go语言的goroutine特性,将程序中的瓶颈并行化。通过使用协程,可以充分利用多...
    99+
    2023-10-22
    go语言
  • go语言快速入门的方法有哪些
    想要快速入门可以通过官方文档和教程、在线课程和视频教程、书籍、练手项目、社区和论坛等等方法学习go语言。详细介绍:1、官方文档和教程:Go语言官方网站提供了丰富的文档和教程,包括官方文档、指南、教程和示例代码,可以帮助初学者快速了解Go语言...
    99+
    2023-12-11
    go语言
  • go语言内存管理的方法有哪些
    Go语言内存管理的方法有以下几种:1. 垃圾回收(Garbage Collection):Go语言使用自动垃圾回收机制来管理内存。垃...
    99+
    2023-09-27
    go语言
  • Go语言的错误处理方法有哪些
    这篇文章主要介绍了Go语言的错误处理方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go语言的错误处理方法有哪些文章都会有所收获,下面我们一起来看看吧。与其他语言的快速比较在 Go 中,所有的错误都是值...
    99+
    2023-06-17
  • go语言错误处理的方法有哪些
    Go语言中的错误处理方法有以下几种:1. 返回错误值:函数可以返回一个额外的错误值,通常是一个error类型的值,用于表示函数执行过...
    99+
    2023-08-15
    go语言
  • oracle表空间扩容的方法有哪些
    自动扩展:可以通过设置表空间的AUTOEXTEND参数为ON来实现自动扩展。当表空间中的数据文件达到最大容量时,系统会自动增加其...
    99+
    2024-04-23
    oracle
  • go的语言有哪些
    go的语言有基本类型、数组、切片、字典、结构体、接口、函数、通道和接收器。1、基本类型,包括布尔型、整数型、无符号整数型和浮点型等;2、数组,具有固定长度且类型一致的数据结构;3、切片,基于数组实现的,可以从已有的数组或切片中创建;4、字典...
    99+
    2023-07-31
  • go语言有哪些库
    go语言有fmt库、net/http库、time库、encoding/json库、database/sql库、log库、testing库、gin库、gorm库、viper库和go-crypto库。1、fmt库,提供了格式化字符串、输入输出等...
    99+
    2023-07-31
  • go语言都有哪些
    go语言都有高效的并发编程、快速编译、内存管理、强大的标准库、静态类型和类型推断、跨平台支持、开源社区支持等特点。详细介绍:1、高效的并发编程,Go语言内置了轻量级的协程和通道,使并发编程变得简单且高效;2、快速编译,Go语言的编译速度非常...
    99+
    2023-08-03
  • go语言中遍历数组的方法有哪些
    这篇文章主要介绍了go语言中遍历数组的方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇go语言中遍历数组的方法有哪些文章都会有所收获,下面我们一起来看看吧。遍历数组有两种方法:1、用for循环语句遍历数...
    99+
    2023-07-05
  • Go语言拼接URL路径的方法有哪些
    这篇文章主要介绍“Go语言拼接URL路径的方法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go语言拼接URL路径的方法有哪些”文章能帮助大家解决问题。Go语言拼接URL路径有多种方法建议用R...
    99+
    2023-07-05
  • go语言大小写转换的方法有哪些
    在Go语言中,可以通过以下几种方法实现大小写转换:1. 使用`strings`包中的函数:- `strings.ToUpper(str)`:将字符串转换为大写形式。- `strings.ToLower(str)`:将字符串转换为小写形式...
    99+
    2023-08-09
    go语言
  • Go语言实现的语言有哪些
    这篇文章主要讲解了“Go语言实现的语言有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言实现的语言有哪些”吧!01 Go+这是国内七牛老大许式伟主导的,对 Go 语言的扩展,专为数...
    99+
    2023-06-15
  • go语言项目有哪些
    知名的go语言项目有Docker、Kubernetes、Prometheus、Etcd、Golang.org、Hugo、CockroachDB等。详细介绍:1、Docker提供了轻量级容器虚拟化的解决方案,能够快速部署和管理应用程序;2、K...
    99+
    2023-07-31
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作