当前位置: 首页 > 面试题库 >

Golang切片追加与分配性能

梁烨
2023-03-14
问题内容

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

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给切片元素的最低要求 ,切片类型
的局部变量a(它是切片标头) 也必须在循环的每个循环中进行更新

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



 类似资料:
  • 如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。下面的代码描述了从拷贝切片的 copy 函数和向切片追加新元素的 append 函数。 示例 7.12 copy_append_slice.go package main import "fmt" func main() { sl_from := []int{1, 2, 3} sl_to := mak

  • 本文向大家介绍Golang slice切片操作之切片的追加、删除、插入等,包括了Golang slice切片操作之切片的追加、删除、插入等的使用技巧和注意事项,需要的朋友参考一下 本文介绍了Golang slice切片操作之切片的追加、删除、插入等,分享给大家,具体如下: 一、一般操作 1,声明变量,go自动初始化为nil,长度:0,地址:0,nil 2,切片的追加,删除,插入操作 3,copy的

  • Go语言中切片的cap和len有什么区别? 根据定义: 切片既有长度也有容量。 切片的长度是它包含的元素数。 切片的容量是底层数组中的元素数,从切片中的第一个元素开始计数。 len是否仅表示非空值?

  • 这是我的控制台中的日志格式。我正在使用spring cloud stream将我的日志从应用程序传输到logstash,这是logstash中的日志解析格式 这是我的logstash.conf 这是我在log-stash控制台中的输出。这是解析异常 {“message”=>“[{\”traceid\“:\”411a0496b048bcf4\“,\”parentId\“:\”8d40fcfea926

  • 我试图理解如何在Go中操作数据结构,以及它指向指针(带有副本或引用)的方法。 我的代码在Go Playground这里:https://play.golang.org/p/j_06RS5Xcz 我制作了一个结构的切片图,里面还有一个其他东西的切片。 在这里: 我想在以后的程序中附加其他项。似乎我必须使用指针来解决这个问题,但我不知道如何解决。 我的实体应该是这样吗? 如果是这样的话,我应该如何向它

  • 问题内容: 我如何将下面的切片查询写入golang? 尝试过但不起作用 找不到任何东西。有任何想法吗? 先感谢您 问题答案: 使用只能指定过滤器。但是,您有一个预测: 可以使用来指定投影,因此这就是您可以应用in投影的方式: 另请注意,确定您过滤的属性是还是只是一个错字,应该是。如果是后者,您还可以使用按文档ID查询: