切片初始化
切片使用内置的make函数进行初始化,初始化需要提供两个参数,分别是切片的长度和容量(可选)。如果这两个参数设置的不合理,会使得后续对切片的操作非常低效。下面来看看怎么设置这两个参数是合适的。
假设我们要实现一个转换函数(convert),将Foo切片映射到Bar切片,并且两个切片将具有相同数量的元素。下面是第一个实现版本:
func convert(foos []Foo) []Bar {
bars := make([]Bar, 0)
for _, foo := range foos {
bars = append(bars, fooToBar(foo))
}
return bars
}
问题分析
上述实现中,首先通过make初始化了一个大小为0的空切片,然后通过append向里面添加元素,在添加第一个元素的时候会分配一个大小为1的底层数组。每次当底层数组满时会创建一个容量加倍的数组。所以在添加第三个、第五个和第九个元素时,由于当前数组已满而创建另一个数组的逻辑会重复多次。假设向切片添加1000个元素,根据Go切片扩容算法,差不多要分配10次底层数组,并将总共1000多个元素从一个数组复制到另一个数组。这会导致GC需要付出额外的努力来清理不在使用的数组。如何进行优化呢?有两种不同的方法。
如何优化?
方法1
方法一代码逻辑与上述一致,唯一区别是一开始将切片的容量设置为给定要装的元素数量。代码如下:
func convert(foos []Foo) []Bar {
n := len(foos)
bars := make([]Bar, 0, n)
for _, foo := range foos {
bars = append(bars, fooToBar

本文探讨了Go语言中切片初始化的优化策略,比较了通过make函数分配给定长度或容量的方法,发现给定预期大小能显著提高性能。特殊情况中,权衡代码可读性和性能是关键。
最低0.47元/天 解锁文章
2059

被折叠的 条评论
为什么被折叠?



