性能优化 | 青训营笔记

70 阅读2分钟

性能优化

slice预分配内存

  • 尽可能在使用make() 初始化切片时提供容量信息
go
复制代码
func PreAlloc(size int) {
    data := make([]int, 0, size)
    for k := 0; k < size; k++ {
        data = append(data, k)
    }
}
  • 在已有切片基础上创建切片,不会创建新的底层数组,所以原底层数组在内存中有引用得不到释放,可以使用copy代替原切片
go
复制代码
func GetLastBySlice(origin []int) []int {
    return origin[len(origin)-2:]
}
​
func GetLastByCopy(origin []int) []int {
    result := make([]int, 2)
    copy(result, origin[len(origin)-2:])
    return result
}

map预分配内存

  • 尽量不使用bytes.Buffer,使用strings.Builder

空结构体

  • 空结构体 struct{} 实例不占据任何的空间
  • 节省资源
  • 空结构体本身具备很强的语义,即这里仅作为占位符

atomic包

在多线程场景下使用该包可以保证计数器技术准确,线程安全

  • atomic操作时通过硬件实现的,效率比锁高
  • 对于仅仅保护一个变量,建议使用atomic包,因为sync.Mutex不仅仅保护一个变量,还用来保护一段逻辑
  • 对于非数值操作,可以使用atomic.Value,能承载一个接口

pprof

用于可视化和分析性能分析数据的工具,使用它可以知道应用在什么地方耗费了多少cpu、memory等指标

使用

  1. 在代码中引入了nethttpprof包,会将pprof的入口注册到/debug/pprof路径下

  2. 在浏览器中打开http://localhost:6060/debug/pprof

image-20230122214524852.png allocs:内存分配情况

arduino
复制代码
blocks:阻塞操作情况

cmdline:显示运行进程的命令

goroutine:当前所有goroutine的堆栈信息

heap:堆上内存使用情况

mutex:锁竞争操作情况

profile:CPU占用情况

threadcreate:当前所有创建的系统线程的堆栈信息

trace:程序运行跟踪信息
  1. 在终端运行 go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10",等待采样数据展示到终端

  2. 输入top n查看cpu占用最高的函数,默认十个 image-20230122220310067.png

    从左到右依次是当前函数本身的执行耗时、flat占用cpu总时间的比例、上面每一行flat%的总和、当前函数本身加上其调用函数的总耗时、cum占cpu总时间的比例

  3. 输入list 正则表达式 查找代码行

  4. 也可以输入web 生成一张调用关系图,默认用浏览器打开

  5. go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"