这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
性能优化指南
性能优化需要在满足正确性、可靠性、健壮性、可读性等质量因素的前提下,设法提高程序的性能。有时候时间效率和空间效率可能对立,此时应当分析哪个更重要,作出适当的折衷。比如多花费一些内存来提高性能。
benchmark工具
性能表现要用数据说话,实际情况和想象中的并不一定一致,要用数据来验证我们写的代码是否真的有性能提升。
go语言自带性能分析工具,叫benchmark。例如需要统计内存信息,就可以使用
go test -bench=. -benchmem
- benchmark结果说明
性能优化要点
slice
- 内存预分配:尽可能在使用
make()初始化切片时提供容量信息,尤其是在追加切片时。 - 当原切片由大量的元素构成,但是我们在原切片的基础上切片,虽然只使用了很小一段,但底层数组在内存中仍然占据了大量空间,得不到释放,此时可使用
copy替代re-slice。
map
- 进行内存预分配
string
- 使用
strings.Builder进行字符串处理
空结构体
- 空结构体不占任何的内存空间
- 可以使用空结构体来节省内存
atomic包
- 在多线程编程场景时,建议使用atomic来代替lock
性能调优原则
- 要依据数据而不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
性能分析工具——pprof
性能调优的核心是性能瓶颈的分析,对于 Go 应用程序,最方便的就是 pprof 工具
-
pprof 功能说明
-
pprof 是用于可视化和分析性能分析数据的工具
-
可以知道应用在什么地方耗费了多少 CPU、memory 等运行指标
-
-
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 采样
- 堆内存采样
- 协程和系统线程采样
- 阻塞操作和锁竞争采样