Golang切片追加与分配性能 [英] Golang slice append vs assign performance

查看:602
本文介绍了Golang切片追加与分配性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To make slice append operation faster we need to allocate enough capacity. There's two ways to append slice, Here is the code:

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

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

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

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

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

a[i] = i is faster than a = append(a, i) and I wanna know why?

推荐答案

a[i] = i只是将值i分配给a[i].这不是附加,只是一个简单的分配.

a[i] = i simply assigns the value i to a[i]. This is not appending, it's just a simple assignment.

现在添加:

a = append(a, i)

理论上会发生以下情况:

In theory the following happens:

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

  1. This calls the builtin append() function. For that, it first has to copy the a slice (slice header, backing array is not part of the header), and it has to create a temporary slice for the variadic parameter which will contain the value i.

然后,如果像a = a[:len(a)+1]这样具有足够的容量(在您的情况下具有),则必须重新切片a-这涉及将新切片分配给append()中的a.
(如果a的容量不足以执行就地"附加操作,则必须分配一个新数组,复制切片中的内容,然后执行assign/append-但情况并非如此.)

Then it has to reslice a if it has enough capacity (it has in your case) like a = a[:len(a)+1] - which involves assigning the new slice to a inside the append().
(If a would not have big enough capacity to do the append "in-place", a new array would have to be allocated, content from slice copied, and then the assign / append be executed - but it is not the case here.)

然后将i分配给a[len(a)-1].

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

Then returns the new slice from append(), and this new slice is assigned to the local variable a.

与简单的任务相比,这里发生了很多事情.即使对这些步骤中的许多步骤进行了优化和/或内联,作为将i分配给切片元素的最低要求,也是切片类型的局部变量a (这是切片标头)必须在循环的每个周期中更新.

A lot of things happen here compared to a simple assignment. Even if many of these steps are optimized and / or inlined, as a minimum addition to assigning i to an element of the slice, the local variable a of slice type (which is a slice header) has to be updated in each cycle of the loop.

推荐阅读: The Go博客:数组,切片(和字符串):追加"的机制

这篇关于Golang切片追加与分配性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆