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