尽可能指定容器容量,以便为容器预先分配内存。这将在添加元素时最小化后续分配(通过复制和调整容器大小)。

指定Map容量提示

在尽可能的情况下,在使用 make() 初始化的时候提供容量信息

make(map[T1]T2, hint)

make()提供容量提示会在初始化时尝试调整map的大小,这将减少在将元素添加到map时为map重新分配内存。

注意,与slices不同。map capacity提示并不保证完全的抢占式分配,而是用于估计所需的hashmap bucket的数量。
因此,在将元素添加到map时,甚至在指定map容量时,仍可能发生分配。

BadGood
m := make(map[string]os.FileInfo)

files, _ := ioutil.ReadDir("./files")
for _, f := range files {
    m[f.Name()] = f
}

files, _ := ioutil.ReadDir("./files")

m := make(map[string]os.FileInfo, len(files))
for _, f := range files {
    m[f.Name()] = f
}

m 是在没有大小提示的情况下创建的; 在运行时可能会有更多分配。

m 是有大小提示创建的;在运行时可能会有更少的分配。

指定切片容量

在尽可能的情况下,在使用make()初始化切片时提供容量信息,特别是在追加切片时。

make([]T, length, capacity)

与maps不同,slice capacity不是一个提示:编译器将为提供给make()的slice的容量分配足够的内存,
这意味着后续的append()`操作将导致零分配(直到slice的长度与容量匹配,在此之后,任何append都可能调整大小以容纳其他元素)。

BadGood
for n := 0; n < b.N; n++ {
  data := make([]int, 0)
  for k := 0; k < size; k++{
    data = append(data, k)
  }
}
for n := 0; n < b.N; n++ {
  data := make([]int, 0, size)
  for k := 0; k < size; k++{
    data = append(data, k)
  }
}
BenchmarkBad-4    100000000    2.48s
BenchmarkGood-4   100000000    0.21s
最后编辑: kuteng  文档更新时间: 2021-05-09 20:12   作者:kuteng