2 回答
TA贡献1818条经验 获得超8个赞
区别在于切片的内存是预先分配的,并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
这是一个简单的任务。
TA贡献1777条经验 获得超3个赞
我的问题是,如果稍后我们可以继续添加项目,那么在“制作”切片时给出零(或 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
告诉我们需要更大的空间。
- 2 回答
- 0 关注
- 108 浏览
添加回答
举报