Golang容器:切片

切片slice

动态分配大小连续的空间,切⽚是引⽤类型,当将⼀个切⽚赋值给另⼀个切⽚时,它们引⽤的是相同的底层数组。修改⼀个切⽚的元素会影响到其他引⽤该底层数组的切⽚。切⽚本身不存储元素,⽽是引⽤⼀个底层数组。切⽚的底层数组会在需要时进⾏动态扩展。

数据结构

go 复制代码
type slice struct {
    array unsafe.Pointer //指向底层数组的指针
    len   int //长度
    cap   int //容量
}

切片(slice)本身并非动态数组或数组指针。它内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。

go 复制代码
//切片声明定义
var s[] int
s:=make([]int,0)
//访问切片,i是切片下标,v是元素的值,可以通过i修改切片的值,不能通过v
for i,v:=range s{
	fmt.Println(v)
}
//添加元素
s:=append(s,5,5,5)
//复制
copy( dest Slice, src Slice []T) int

数据被追加到原底层数组。如超出cap限制,由于数组长度的不变性,当涉及底层数组大小无法满足要求时,会创建新的数组。切片容量的扩展是通过底层数组的重建来完成的。append()函数执行时,会首先将传入的切片参数复制一份,生成一个新的切片,

在 Go 1.18 之前的版本中,切片扩容遵循的策略是:对于容量小于 1024 个元素的切片,扩容时容量翻倍;而对于容量超过 1024 的切片,每次扩容增加现有容量的 25%,直至满足需求。

从 Go 1.18 版本开始,Go 语言对切片扩容策略进行了优化,以更高效地处理大容量切片的扩容问题,减少内存分配和拷贝的开销。优化后的扩容策略遵循以下原则:

  1. 容量增长:新容量至少等于原容量加上所需的额外空间,确保扩容满足需求。
  2. 高效内存分配:避免频繁的小幅度扩容,实现内存分配的高效性。

具体优化点包括:

  • 阈值调整:扩容策略的阈值从 1024 字节调整为 256 字节。当切片容量小于 256 字节时,容量增长速度为 2 倍;超过 256 字节后,增长速度减慢至 1.25 倍。
  • 扩容系数平滑过渡 :Go 1.18 引入了新的算法,使得在阈值附近扩容系数能够平滑过渡。具体算法为 (newcap + 3*threshold) / 4,其中 threshold 为 256 字节,这有助于避免扩容系数从 2 倍到 1.25 倍的突然变化。
  • 避免溢出:新策略还包括对潜在溢出的检查,确保在计算新容量时不会发生溢出,避免无限循环,并在必要时将新容量设置为请求的容量大小。
相关推荐
八解毒剂11 分钟前
【计组】中央处理器CPU
java·开发语言·计算机组成原理
FakeOccupational1 小时前
【电路笔记 信号】DBPSK 波形查找表+脉冲成形(升余弦+根升余弦滤波)
开发语言·笔记
打工仔折腾 AI1 小时前
工业场景下时序库与实时计算一体化架构选型实践对比
java·开发语言·后端·python·性能优化·架构·ai agent 实战
ZealSinger1 小时前
Java虚拟线程上线后瓶颈转移到哪看三层
java·开发语言·firefox
蜗牛互联网1 小时前
长任务多Agent共享文件系统的Manifest交接模式
java·人工智能·后端
茉莉玫瑰花茶2 小时前
GO [ 泛型 ]
golang
weixin_440730503 小时前
函数return、参数、参数组、递归函数、高阶函数等小结
开发语言·python
苏supper3 小时前
Spring Boot多环境配置与打包运行
spring boot·后端·spring
sugarzhangnotes3 小时前
【无标题】
开发语言·人工智能·python
geovindu3 小时前
rust: Composite Pattern
开发语言·后端·设计模式·rust·组合模式