Go中切片slice的两种性能优化方法

研究 Go 中的优化技术,优化一些似乎不太高效的最佳实践,主要是关于切片slice和映射map的。

下面是我遇到的几个例子,作为开场白:

1、在每次迭代时重新分配切片/映射:

go for { queue := []int{}// 对队列的操作}

}这种模式会在一个循环内重复分配新的切片,可能会因持续的内存分配和垃圾回收而导致性能问题。

一种更优化的方法:

go queue := []int{} for { queue = queue[:0] // 对 queue 的操作 }

这种方法重复使用了已分配的片段,可能会提高性能。


2、在函数周围传递增长Slice:

go func main() {
  queue := []int{} for { queue = queue[:0] // reset doStuff(queue) }
}
func doStuff(queue []int) { for {
  queue = append(queue, 1)
// 追加操作
   
// 其他操作...
  }
}

这里,不断增长的slice可能会导致与Slice片头的同步问题,影响内存效率。

另一种方法是通过引用传递片:

go func main() { queue := []int{} for {
   queue = queue[:0] doStuff(&queue) }
}}

func doStuff(queue []int) {
    *queue = append(queue, 1)
}

通过传递指向片slice的指针,函数内部对片的片头(SliceHeader)的修改也会反映到外部,从而保持片的同步。