growslice扩容 runtime/slice.go
// 测试代码
// go1.18
func testAppend() {
var a []byte
// 打印效果
// loop 0 a size 1 cap 8
// ...
// loop 8 a size 9 cap 16
// ...
// loop 16 a size 17 cap 32
// ...
// loop 32 a size 33 cap 64
// ...
// loop 64 a size 65 cap 128
// ...
// loop 128 a size 129 cap 256
// ...
// loop 256 a size 257 cap 512
// ...
// loop 512 a size 513 cap 1024
// ...
// loop 1024 a size 1025 cap 1280 (1024+1024/4 = 1280 <= 1280)
// ...
// loop 1280 a size 1281 cap 1792 (1280+1280/4 = 1600 <= 1792)
// ...
// loop 1792 a size 1793 cap 2304 (1792+1792/4 = 2240 <= 2304)
// ...
// cap < 1024,cap = cap * 2
// cap >= 1024, cap = roundupsize(cap + 1/4*cap)。roundupsize的作用就是在表class_to_size中匹配一个大于的值
// class_to_size=[...,1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200,]
for i := 0; i < 2000; i++ {
a = append(a, 'a')
fmt.Printf("loop %d a size %d cap %d\n", i, len(a), cap(a))
}
}
go1.21版本已经改动
// 测试代码
func testAppend() {
var a []byte
var lastCap int
for i := 0; i < 2000; i++ {
a = append(a, 'a')
if lastCap != cap(a) {
fmt.Printf("loop %d a size %d cap %d\n", i, len(a), cap(a))
lastCap = cap(a)
}
}
}
/*
loop 0 a size 1 cap 8
loop 8 a size 9 cap 16
loop 16 a size 17 cap 32
loop 32 a size 33 cap 64
loop 64 a size 65 cap 128
loop 128 a size 129 cap 256
loop 256 a size 257 cap 512
loop 512 a size 513 cap 896
loop 896 a size 897 cap 1408
loop 1408 a size 1409 cap 2048
*/