golang切片扩容机制

2023年 7月 12日 35.3k 0

前言

golang的切片扩容机制是golang面试者绕不开的一扇大门,无论在面试提问,或者面试情景上都绕不开它,今天就说说我理解下的切片扩容。

golang的扩容机制:在go1.18之前有一个临界值为1024,小于1024的时候,切片先两倍扩容,如果两倍扩容后的容量还是不够,就直接以切片需要的容量作为容量。

在go1.18之后,临界值换成了256,小于256和前面相同,大于256公式变为(oldcap+3*256)/4这个公式的值随着oldcap的越来越大,从2一直接近1.25,相对于1.18之前可以更平滑的过渡。

上面就是切片扩容的基本规则机制,但还有一个小的规则,下面就来看看

发现问题

看下面一行代码

image.png

运行结果如下

image.png

出现上面的结果原因是,刚开始切片容量为1,两倍扩容之后,变为2,但是2不够,所以变为所需要的容量3,后面在加4个数字,继续扩容,2倍之后是6,但是6不够应该变为需要的容量,应该为7,为什么是8呢

解决问题

先贴一下源代码,下面第一段代码是扩容机制的基础代码(1.18之前)

image.png

下面是造成上面原因的代码

image.png

下面是1.18之后的基础扩容机制

image.png

从上面代码分析之后,造成7变成8的原因就在这个roundupsize函数上面,它有一个计算公式

capmem = roundupsize(uintptr(newcap) * ptrSize)
newcap = int(capmem / ptrSize)

其中 ptrSize 在 64 位机器下的大小为 8。 而此时 newcap 的值为 7,所以传入到 roundupsize 函数内部的值为 7 * 8 = 56 。接着看看 roundupsize 的内部:

func roundupsize(size uintptr) uintptr {
if size < _MaxSmallSize {
if size

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论