Go Slice的扩容机制
Go Slice的扩容机制
在Go语言中使用append()
函数向Slice添加元素,扩容也是发生在append的调用中,当切片内部的容量,不足以容纳新增元素时就会触发Slice的扩容。
并非每次调用append()
函数都会触发扩容,因为扩容涉及到内存分配,会减缓append
的速度。本文将从底层分析,以展现Slice切片扩容的具体策略。
扩容机制
1.扩容时机
func SliceExpansion() {
sliceA := make([]int, 3, 4)
sliceA = append(sliceA, 1) // 未扩容
fmt.Printf("SliceA len: %v, cap: %v\n", len(sliceA), cap(sliceA))
sliceB := make([]int, 3, 3)
sliceB = append(sliceB, 1) // 触发扩容
fmt.Printf("SliceB len: %v, cap: %v\n", len(sliceB), cap(sliceB))
}
可见SliceA 初始len=3,初始cap=4;SliceB 初始len=3,初始cap=3,向SliceA 追加一个元素时,由于SliceA追加元素后len<cap并未发生扩容,而向SliceB 追加一个元素时,由于SliceB追加元素后len>=cap发生扩容,且扩容后容量为6,看上去好像扩容就是在原来Slice长度的基础上增加一倍容量,事实上也是如此吗?
2.扩容策略
当Slice的当前容量不足以容纳新增元素与原长度之和时会发生Slice的扩容,扩容的核心逻辑代码为 growSlice()
func growslice(et *_type, old slice, cap int) slice {
// 将当前容量取出
newcap := old.cap
// 当前容量*2
doublecap := newcap newcap
// cap:预估容量是否大于两倍的当前容量
if cap > doublecap {
// 新容量 = 预估容量
newcap = cap
} else {
// 当前容量是否小于1024
if old.cap < 1024 {
// 两倍扩容
newcap = doublecap
} else {
// Check 0 < newcap to detect overflow
// and prevent an infinite loop.
// 新容量 = 循环增加1.25倍,直至newcap > cap
for 0 < newcap && newcap < cap {
newcap = newcap / 4
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
// 如果经过循环1.25增加,最终newcap计算值溢出,即超过了int的最大范围,则最终容量就是新申请的容量
if newcap <= 0 {
newcap = cap
}
}
}
............
// 内存分配相关
............
// 将原数组复制到新地址
memmove(p, old.array, lenmem)
// 返回新创建的结构体
return slice{p, old.len, newcap}
}
上面代价显示了Slice扩容的核心逻辑,Go语言中切片的扩容策略为:
- **策略一:**如果新申请的容量(cap)大于2倍的旧容量(old.cap),则最终容量(nwecap)是新申请的容量。
- **策略二:**如果不满足策略一
- 如果旧切片len<1024,则最终容量是就容量的2倍,即newcap = doublecap。
- 如果旧切片len>=1024,则最终容量循环增加1.25倍,直至newcap > cap 为止。
- **策略三:**在进行循环1.25倍计算时,最终容量计算值发生溢出,即超过了int的最大范围,则最终容量就是新申请的容量。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfbcfa
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01