Golang原理分析:切片(slice)原理及扩容机制
创始人
2024-03-17 19:53:45

在这里插入图片描述

《Go语言精进之路》切片相关章节学习笔记及实验。

1.切片原理

说切片之前,先看看Go语言数组。Go数组是一个固定长度的、容纳同构类型元素的连续序列,因此Go数组类型具有两个属性:长度及类型:

var a [1]int
var b [2]byte
var c [3]string

数组的特性是声明即定长,无法原地进行扩容,所以Golang中一般来说需要使用到数组的场合都会使用切片来替代。

切片的特性:

  • 不定长,能随着存储容量进行自动扩容
  • 提供append函数,能够方便地添加值

切片的本质是引用底层数组头指针+当前切片长度+底层数组大小:即array、len和cap:

  • $goroot/src/runtime/slice.go
type slice struct {array unsafe.Pointer    // 底层数组头指针len   int               // 当前切片长度 cap   int               // 底层数组最大容量
}

使用时通过make关键字来进行初始化切片分配一个新的底层数组,或者是基于指定的数组进行切片化:

  • make关键字,创建一个长度为5的切片,如果没有指定cap参数则默认与长度一致为5(底层数组长度也为5)
s := make([]byte,5)

在这里插入图片描述

  • 直接通过已有数组创建切片,array指向底层数组的指定位置作为头部,从头部开始计算len及cap:
u := [10]byte{11,12,13,14,15,16,17,18,19,20} // 长度为10的数组
s := u[3:7] // 从数组的第3个元素至第6个元素建立切片(前闭后开区间)

在这里插入图片描述

  • 底层数组可以被多个切片共享,如果切片共享了底层数组同一值,那么切片1进行修改后,切片2读取该值时也会读取到修改的结果:
    在这里插入图片描述

2.扩容机制

切片能够在底层数组容量不够时进行扩容,每次append时如果容量不足,会创建2倍大小于老数组的新数组,并复制老数组数据至新的数组中:

func main() {var s []int                // 初始化时,底层数组为数组为nils = append(s, 11)          fmt.Println(len(s), cap(s)) // 1 1s = append(s, 12) fmt.Println(len(s), cap(s)) // 2 2s = append(s, 13)fmt.Println(len(s), cap(s)) // 3 4s = append(s, 14)fmt.Println(len(s), cap(s)) // 4 4s = append(s, 15)fmt.Println(len(s), cap(s)) // 5 8
}

在这里插入图片描述

  • 扩容存在损耗,所以尽可能在已知数据最长度的情况下声明切片的cap,避免频繁库容切换底层数组带来的性能损耗:
func BenchmarkAppendZeroSlice(b *testing.B) {maxNum := 10000for i := 0; i < b.N; i++ {// 空切片var zeroSlice []intfor j := 0; j < maxNum; j++ {zeroSlice = append(zeroSlice, j)}}
}func BenchmarkAppendCapSlice(b *testing.B) {maxNum := 10000for i := 0; i < b.N; i++ {// 声明cap的切片capSlice := make([]int, 0, maxNum)for j := 0; j < maxNum; j++ {capSlice = append(capSlice, j)}}
}

在这里插入图片描述

从基准测试结果可以看出,声明了cap的切片能避免频繁创建底层数组及复制,单轮append时间为18847ns,相较于零值切片的82081ns提升了4.3倍性能。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...