使切片大小

时间:2018-12-17 03:49:04

标签: go allocation

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

<form action="/test.aspx">
  <input type="file" multiple>
  <input type="submit">
</form>
<div id="fileList"></div>

然后稍后我可以使用内置的append函数添加元素:

my_slice := make( []int, 0 )

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

通过猜测切片最终将具有的容量来获得性能上的好处吗?

2 个答案:

答案 0 :(得分:2)

区别在于切片的内存是预先分配的,len(mySlice)返回切片的总长度。

从性能角度来说,最好预先分配大小,因为调用a = append(a, n)时会发生以下情况:

  • 它调用内置的append函数,并为此首先复制a slice(切片标头,后备数组不是标头的一部分),并且必须为可变参数创建临时切片参数,它将包含值n

  • 然后,如果它具有a之类的足够容量,则必须重新切片a = a[:len(a)+1]-这涉及在append函数中将新切片分配给a。如果a的容量不足以执行“就地”附加操作,则必须分配一个新数组,复制切片中的内容,然后执行assign / append。

  • 然后将n分配给[len(a)-1]

  • 然后从append函数返回新切片,并将此新切片分配给局部变量a

a[i] = n相比,这是一个简单的赋值。

答案 1 :(得分:-1)

  

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

分配不当会导致重新分配。

  

通过猜测切片最终将具有的容量来获得性能上的好处吗?

是的,重新分配将导致切片上的其他副本。

  

切片:大小指定长度。切片的容量为   等于它的长度。可以提供第二个整数参数   指定不同的容量;它必须不小于长度。

     

例如,make([] int,0,10)分配一个大小为1的基础数组   10并返回长度为0且容量为10的切片,该切片由   此基础数组。

从go doc复制。

在我看来。切片就像c / c ++中具有长度和容量的指针。追加到切片将在该指针的偏移量之后追加元素。容量是顺序空间的总大小。一旦capacity-allocated空间不足,append将在分片上进行重新分配和复制。

  

make(s, 1)

去做比您想像的要多:

  1. 分配一个大于您提供的大小的顺序空间(与c ++向量相同),以避免重新分配,否则可能导致性能降低。

  2. 初始化您在make中给出的尺寸。 (RAII)

  3. 一旦发生重新分配,go将分配两倍大小的顺序空间,并将旧切片复制到该位置。这也会降低性能。

为避免发生重新分配,我们可以在make中提供可选的容量参数,以告诉我们我们需要更大的空间。