制作切片大小

在 Golang 中,您可以使用以下语法为切片分配内存:

my_slice := make( []int, 0 )

稍后我可以使用内置的追加函数添加元素,如下所示:

my_slice := append(my_slice, 23)

我的问题是,如果稍后我们可以继续添加项目,那么在“制作”切片时给出零(或 2 或 5 或其他)有什么区别?

尝试猜测切片最终拥有的容量是否有性能奖励?


BIG阳
浏览 109回答 2
2回答

弑天下

区别在于切片的内存是预先分配的,并len(mySlice)返回切片的总长度。在性能方面,预先分配大小是有益的,因为当您调用a = append(a, n)以下内容时:它调用内置的 append 函数,为此它首先复制切片a(切片标头,支持数组不是标头的一部分),并且它必须为包含值的可变参数创建一个临时切片n。a如果它有足够的容量,那么它必须重新切片a = a[:len(a)+1]- 这涉及将新切片分配给a附加函数内部。如果 a 没有足够大的容量来“就地”进行追加,则必须分配一个新数组,复制切片中的内容,然后执行分配/追加。然后分配n给 a [len(a)-1]。然后从 append 函数返回新的切片,并将这个新切片赋值给局部变量a。与之相比,a[i] = n这是一个简单的任务。

慕森王

我的问题是,如果稍后我们可以继续添加项目,那么在“制作”切片时给出零(或 2 或 5 或其他)有什么区别?不适当的分配会导致重新分配。尝试猜测切片最终拥有的容量是否有性能奖励?是的,重新分配会导致切片上有额外的副本。切片:大小指定长度。切片的容量等于它的长度。可以提供第二个整数参数来指定不同的容量;它必须不小于长度。例如,make([]int, 0, 10) 分配一个大小为 10 的底层数组,并返回由该底层数组支持的长度为 0、容量为 10 的切片。从 go doc 复制。在我看来。Slice就像c/c++中的指针,有长度有容量。附加到切片将在该指针的偏移量之后附加元素。容量是总的顺序空间大小。一旦capacity--allocated空间不够,append会导致slice上的重新分配和复制。make(s, 1)go 会做的比你想象的更多:分配一个大于您给定大小的顺序空间(在 C++ 向量中相同)以避免可能导致性能低下的重新分配。初始化你在 make 中给定的大小。(RAII)一旦发生重新分配,go 将分配两倍大小的顺序空间并将旧切片复制到该位置。这也会降低性能。为了避免重新分配发生,我们可以提供可选的容量参数来make告诉我们需要更大的空间。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go