代码改变世界

go 切片扩容案例分析

2022-01-10 17:00  天心PHP  阅读(73)  评论(0编辑  收藏  举报

类型的大小计算

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   因为上一步已经扩容到了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) //结果长度为:5 容量为:8
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) //结果:长度为5 容量为:8
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)) //100
s5 = append(s5, 1)
fmt.Println("扩容后容量:",cap(s5)) //224
//分析 最开始 100  新增 1   100*2>100+1  最终扩容为 200  int大小为8  则  200*8=1600  取内存表格  1536<1600<1792  取 1792  1792/8=224