Golang切片追加与分配性能

为了使切片追加操作更快,我们需要分配足够的容量。有两种附加切片的方法,下面是代码:

func BenchmarkSliceAppend(b *testing.B) {

a := make([]int, 0, b.N)

for i := 0; i < b.N; i++ {

a = append(a, i)

}

}

func BenchmarkSliceSet(b *testing.B) {

a := make([]int, b.N)

for i := 0; i < b.N; i++ {

a[i] = i

}

}

结果是:

BenchmarkSliceAppend-4 200000000 7.87 ns / op 8 B / op 0 allocs / op

BenchmarkSliceSet-4 300000000 5.76 ns / op 8 B / op

a[i] = ia = append(a, i)我快,我想知道为什么吗?

回答:

a[i] = i只需将值分配ia[i]。这

附加,只是一个简单的赋值。

现在添加:

a = append(a, i)

理论上会发生以下情况:

  1. 这将调用内置append()函数。为此,它首先必须复制a切片(切片标头,后备数组不是标头的一部分),并且必须为可变参数创建一个临时切片,该临时切片将包含value i

  2. 然后,a如果它具有足够的容量(在您的情况下具有)a = a[:len(a)+1],则必须重新切片-这涉及将新的切片分配到的a内部append()

    (如果a没有足够大的容量来执行“就地”附加操作,则必须分配一个新数组,复制切片中的内容,然后执行assign / append-但这不是这种情况。)

  3. 然后分配ia[len(a)-1]

  4. 然后从返回新切片append(),并将此新切片分配给局部变量a

与简单的任务相比,这里发生了很多事情。即使对这些步骤中的许多步骤进行了优化和/或内联,作为分配i给切片元素的最低要求

(它是切片标头) 。

推荐阅读:The Go Blog:数组,切片(和字符串):“ append”的机制

以上是 Golang切片追加与分配性能 的全部内容, 来源链接: utcz.com/qa/416325.html

回到顶部