04性能优化 | 青训营笔记

86 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天


性能优化指南

性能优化需要在满足正确性、可靠性、健壮性、可读性等质量因素的前提下,设法提高程序的性能。有时候时间效率和空间效率可能对立,此时应当分析哪个更重要,作出适当的折衷。比如多花费一些内存来提高性能。

benchmark工具

性能表现要用数据说话,实际情况和想象中的并不一定一致,要用数据来验证我们写的代码是否真的有性能提升。

go语言自带性能分析工具,叫benchmark。例如需要统计内存信息,就可以使用 go test -bench=. -benchmem

  • benchmark结果说明

image.png

性能优化要点

slice

  1. 内存预分配:尽可能在使用 make() 初始化切片时提供容量信息,尤其是在追加切片时。
  2. 当原切片由大量的元素构成,但是我们在原切片的基础上切片,虽然只使用了很小一段,但底层数组在内存中仍然占据了大量空间,得不到释放,此时可使用 copy 替代 re-slice

map

  • 进行内存预分配

string

  • 使用strings.Builder进行字符串处理

空结构体

  • 空结构体不占任何的内存空间
  • 可以使用空结构体来节省内存

atomic包

  • 在多线程编程场景时,建议使用atomic来代替lock

性能调优原则

  1. 要依据数据而不是猜测
  2. 要定位最大瓶颈而不是细枝末节
  3. 不要过早优化
  4. 不要过度优化

性能分析工具——pprof

性能调优的核心是性能瓶颈的分析,对于 Go 应用程序,最方便的就是 pprof 工具

  • pprof 功能说明

    • pprof 是用于可视化和分析性能分析数据的工具

    • 可以知道应用在什么地方耗费了多少 CPU、memory 等运行指标

      image.png

  • pprof 实践

    • 排查 CPU 问题

      • 命令行分析
        • go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
      • top 命令
      • list 命令
      • web 页面分析
      • 关系图、火焰图
      • go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/cpu"
    • 排查堆内存问题

      • go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
    • 排查协程问题

      • go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
    • 排查锁问题

      • go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
    • 排查阻塞问题

      • go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
  • pprof 的采样过程和原理

    • CPU 采样
    • 堆内存采样
    • 协程和系统线程采样
    • 阻塞操作和锁竞争采样