Golang编码规范之性能01

举报
kaliarch 发表于 2022/03/06 11:53:12 2022/03/06
【摘要】 性能方面的特定准则只适用于高频场景。 一 优先使用 strconv 而不是 fmtBadfor i := 0; i < b.N; i++ { s := fmt.Sprint(rand.Int())}// BenchmarkFmtSprint-4 143 ns/op 2 allocs/opGoodfor i := 0; i < b.N; i++ { s := strconv.I...

性能方面的特定准则只适用于高频场景。

一 优先使用 strconv 而不是 fmt

  • Bad
for i := 0; i < b.N; i++ {
  s := fmt.Sprint(rand.Int())
}

// BenchmarkFmtSprint-4    143 ns/op    2 allocs/op
  • Good
for i := 0; i < b.N; i++ {
  s := strconv.Itoa(rand.Int())
}

// BenchmarkStrconv-4    64.2 ns/op    1 allocs/op

二 避免字符串到字节的转换

不要反复从固定字符串创建字节 slice。相反,请执行一次转换并捕获结果。

  • Bad
for i := 0; i < b.N; i++ {
  w.Write([]byte("Hello world"))
}

// BenchmarkBad-4   50000000   22.2 ns/op
  • Good
data := []byte("Hello world")
for i := 0; i < b.N; i++ {
  w.Write(data)
}

// BenchmarkGood-4  500000000   3.25 ns/op

三 指定容器容量

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

3.1 指定 Map 容量提示

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

make(map[T1]T2, hint)

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

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

  • Bad

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

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

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

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


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

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

3.2 指定切片容量

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

make([]T, length, capacity)

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

  • Bad
for n := 0; n < b.N; n++ {
  data := make([]int, 0)
  for k := 0; k < size; k++{
    data = append(data, k)
  }
}

// BenchmarkBad-4    100000000    2.48s
  • Good
for n := 0; n < b.N; n++ {
  data := make([]int, 0, size)
  for k := 0; k < size; k++{
    data = append(data, k)
  }
}

// BenchmarkGood-4   100000000    0.21s
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。