制作切片大小
Make slices size
在 Golang 中,您可以使用以下语法为切片分配内存:
my_slice := make( []int, 0 )
稍后我可以使用内置追加函数添加元素:
my_slice := append(my_slice, 23)
我的问题是,当 "making" 切片时给零(或 2 或 5 或其他)有什么区别,如果稍后我们可以继续添加项目,只要我们想?
是否可以通过尝试猜测切片最终拥有的容量来获得性能奖励?
不同之处在于切片的内存是预先分配的,len(mySlice)
returns 切片总长度。
在性能方面,预先分配大小是有益的,因为当您调用 a = append(a, n)
时会发生以下情况:
它调用内置的附加函数,为此它首先复制 a
切片(切片头,支持数组不是头的一部分),它必须创建一个临时的包含值 n
.
的可变参数的切片
然后它必须重新切片 a
如果它有足够的容量像 a = a[:len(a)+1]
- 这涉及将新切片分配给附加函数内的 a
。如果 a 没有足够大的容量来执行追加 "in-place" 则必须分配一个新数组,复制切片中的内容,然后执行分配/追加。
然后将n
赋值给一个[len(a)-1]
.
然后returns从append函数中得到新的slice,并将这个新的slice赋值给局部变量a
.
与 a[i] = n
相比,这是一个简单的赋值。
My question is, what's the difference between giving that zero ( or 2 or 5 or whatever) when "making" the slice if later on we can keep adding items as long as we wan?
分配不当会导致重新分配。
Is there a performance bonus by trying to guess the capacity that slice will end up having?
是的,重新分配会导致切片上有额外的副本。
Slice: The size specifies the length. The capacity of the slice is
equal to its length. A second integer argument may be provided to
specify a different capacity; it must be no smaller than the length.
For example, make([]int, 0, 10) allocates an underlying array of size
10 and returns a slice of length 0 and capacity 10 that is backed by
this underlying array.
从 go doc 复制。
在我看来。在c/c++中,Slice 就像一个具有长度和容量 的指针。附加到切片将在该指针的偏移量之后附加元素。容量是总顺序 space 大小。一旦capacity
-allocated
space不够用,append会导致重新分配,并在slice上复制。
make(s, 1)
go 会做的比你想象的要多:
分配一个比您给定的大小更大的顺序 space(在 C++ 向量中相同)以避免可能导致性能低下的重新分配。
初始化你在make中给定的尺寸。 (RAII)
一旦重新分配发生,go 将分配两倍大小的顺序 space 并将旧切片复制到该位置。这也会降低性能。
为了避免重新分配发生,我们可以在 make
中提供可选的容量参数来告诉 go 我们需要更大的 space.
在 Golang 中,您可以使用以下语法为切片分配内存:
my_slice := make( []int, 0 )
稍后我可以使用内置追加函数添加元素:
my_slice := append(my_slice, 23)
我的问题是,当 "making" 切片时给零(或 2 或 5 或其他)有什么区别,如果稍后我们可以继续添加项目,只要我们想?
是否可以通过尝试猜测切片最终拥有的容量来获得性能奖励?
不同之处在于切片的内存是预先分配的,len(mySlice)
returns 切片总长度。
在性能方面,预先分配大小是有益的,因为当您调用 a = append(a, n)
时会发生以下情况:
它调用内置的附加函数,为此它首先复制
a
切片(切片头,支持数组不是头的一部分),它必须创建一个临时的包含值n
. 的可变参数的切片
然后它必须重新切片
a
如果它有足够的容量像a = a[:len(a)+1]
- 这涉及将新切片分配给附加函数内的a
。如果 a 没有足够大的容量来执行追加 "in-place" 则必须分配一个新数组,复制切片中的内容,然后执行分配/追加。然后将
n
赋值给一个[len(a)-1]
.然后returns从append函数中得到新的slice,并将这个新的slice赋值给局部变量
a
.
与 a[i] = n
相比,这是一个简单的赋值。
My question is, what's the difference between giving that zero ( or 2 or 5 or whatever) when "making" the slice if later on we can keep adding items as long as we wan?
分配不当会导致重新分配。
Is there a performance bonus by trying to guess the capacity that slice will end up having?
是的,重新分配会导致切片上有额外的副本。
Slice: The size specifies the length. The capacity of the slice is equal to its length. A second integer argument may be provided to specify a different capacity; it must be no smaller than the length.
For example, make([]int, 0, 10) allocates an underlying array of size 10 and returns a slice of length 0 and capacity 10 that is backed by this underlying array.
从 go doc 复制。
在我看来。在c/c++中,Slice 就像一个具有长度和容量 的指针。附加到切片将在该指针的偏移量之后附加元素。容量是总顺序 space 大小。一旦capacity
-allocated
space不够用,append会导致重新分配,并在slice上复制。
make(s, 1)
go 会做的比你想象的要多:
分配一个比您给定的大小更大的顺序 space(在 C++ 向量中相同)以避免可能导致性能低下的重新分配。
初始化你在make中给定的尺寸。 (RAII)
一旦重新分配发生,go 将分配两倍大小的顺序 space 并将旧切片复制到该位置。这也会降低性能。
为了避免重新分配发生,我们可以在 make
中提供可选的容量参数来告诉 go 我们需要更大的 space.