go 切片扩容案例分析
类型的大小计算
demo1 := true
fmt.Println("bool: ", reflect.TypeOf(demo1).Size())
demo2 := 'a'
fmt.Println("rune: ", reflect.TypeOf(demo2).Size())
demo3 := 1
fmt.Println("int: ", reflect.TypeOf(demo3).Size())
demo4 := "a"
fmt.Println("string: ", reflect.TypeOf(demo4).Size())
结果
bool: 1 rune: 4 int: 8 string: 16
案例分析
s := []string{"a", "b"} // 此时切片长度为2,容量也为2。
s = append(s, "c")
//分析 最开始为 2 新增 1 2*2>2+1 最终扩容为 4 string类型大小为 16 4*16=64 刚好与内存表格64对应 最终容量 64/16 = 4
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s)) // 结果:len=3, cap=4
s = append(s, "d")
//分析 最开始为 3 新增 1 2*2=3+1 最终扩容为 4 string类型大小为 16 4*16=64 刚好与内存表格64对应 最终容量 64/16 = 4
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s)) // 结果:len=3, cap=4
s = append(s, "e")
//分析 最开始为 4 新增 1 4*2>4+1 最终扩容为 8 string类型大小为 16 8*16=128 刚好与内存表格128对应 最终容量 128/16 = 8
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s)) // 结果:len=5, cap=8
s1 := []string{"a", "b"} // 此时切片长度为2,容量也为2。
s1 = append(s1, "c", "d", "e")
fmt.Printf("len=%d, cap=%d\n", len(s1), cap(s1)) // 结果:len=5, cap=5
//分析 最开始 2 新增3 2*2<2+3 最终扩容为 5 string类型大小为 16 则 5*16 = 80 与内存表格对应 80/16=5
s2 := []int{1, 2} // 此时切片长度为2,容量也为2。
s2 = append(s2, 3, 4, 5)
fmt.Printf("len=%d, cap=%d\n", len(s2), cap(s2)) // 结果:len=5, cap=6
//分析 最开始 2 新增 3 2*2<2+3 最终扩容为 5 int大小为 8 则 5*8=40 取内存表格 32<40<48 取 48 48/8=6
s3 := []int8{1,2}
s3 = append(s3, 3, 4, 5)
fmt.Printf("len=%d, cap=%d\n", len(s3), cap(s3))
//分析 最开始 2 新增 3 2*2<2+3 最终扩容为 5 int8大小为1 则 5*1=5 取内存表格 0<5<8 取 48 8/1=8
s4 := []int16{1,2}
s4 = append(s4, 3, 4, 5)
fmt.Printf("len=%d, cap=%d\n", len(s4), cap(s4))
//分析 最开始 2 新增 3 2*2<2+3 最终扩容为 5 int16大小为2 则 5*2=10 取内存表格 8<10<16 取 16 16/2=8
s5 := make([]int, 100)
fmt.Println("扩容前容量:",cap(s5))
s5 = append(s5, 1)
fmt.Println("扩容后容量:",cap(s5))
//分析 最开始 100 新增 1 100*2>100+1 最终扩容为 200 int大小为8 则 200*8=1600 取内存表格 1536<1600<1792 取 1792 1792/8=224