Golang 程序性能优化利器 PGO 详解(二):收集样本数据和编译

在软件开发过程中,性能优化是不可或缺的一部分。无论是在Web服务、数据处理系统还是实时通信中,良好的性能都是至关重要的。Golang 从1.20版版本开始引入的 Profile Guided Optimization(PGO)机制能够帮助更好地优化 Go 程序的性能。

上篇文章讲解了 Golang PGO 的概念和使用方法,并且使用简单的示例演示了 PGO 的使用方法,本文详细讲解一下 PGO 相关的知识点。

收集 profile 数据

Go 编译器需要一个 CPU pprof 文件作为 PGO 的输入。由 Go 运行时生成的文件(也就是使用 runtime/pprof 和 net/http/pprof 包生成的文件,因为具备采集样本数据开销低、多系统兼容性强、Go 官方标准且被广泛使用等优点)可以直接作为编译器输入(其他性能分析工具例如 Linux perf 等生成的 profile 文件只要按照要求转化为 pprof 格式也是可以使用的)。

为了获得最佳结果,最好直接从生产环境中收集 profile 文件。如果收集的 profile 文件不是真实使用环境的,带来的性能提升可能会比较小。即使是从生产环境收集的 profile 文件,也要注意一定要有代表性,即能反映出生产环境的实际情况,以下几种情况是有问题的:

  • 在采集性能分析数据时服务处于空闲状态,即使这个服务大部分时间都是处于负载状态。
  • 每天不同时段的流量可能会不同,只采集了一个时段的数据。
  • 程序执行耗时比较久的任务的场景,例如,5分钟执行任务 A,然后5分钟执行任务 B。如果采集30秒的数据,可能只涵盖了一种操作类型。
  • 负载不均衡的场景,如果一个实例被分配的请求比较少。

比较好的的策略是在不同时段从不同实例收集多个 profile 文件,然后将多个文件合并为单个文件。Golang 提供的 pprof tool 可以合并多个文件,例如:

复制代码
$ go tool pprof -proto a.pprof b.pprof > merged.pprof

如果从生产环境中收集 profile 比较困难或者根本就没办法收集(例如,分发给用户的命令行工具),也可以从有代表性基准测试中收集(需要注意的是,构建具有代表性的基准测试通常也是有一定难度的)。

使用 PGO 编译程序

收集到 profile 文件后,Golang 官方推荐的做法是将文件命名为 default.pgo,并且把 default.pgo 文件存放在程序主目录(main 包所在目录)下维护,以方便项目的其他开发者使用 default.pgo 来对程序做性能优化。默认情况下,go build 将检测 default.pgo 文件,如果检测到则启用 PGO。

对于更复杂的场景,可以使用 -pgo 参数来指定 PGO 配置文件的位置,默认为 -pgo=auto(Go 1.20 默认 -pgo=off )。例如:

复制代码
$ go build -pgo=/tmp/foo.pprof。
相关推荐
闲人编程2 分钟前
使用Python进行量化交易入门
开发语言·python·统计分析·lambda·量化·codecapsule
数据知道13 分钟前
Go语言设计模式:组合模式详解
设计模式·golang·组合模式·go语言
移远通信1 小时前
常见问题解答
开发语言·php
初见无风1 小时前
3.1 Lua代码中的元表与元方法
开发语言·lua·lua5.4
逻极1 小时前
Rust流程控制(上):if_else与match模式匹配
开发语言·后端·rust
小雨下雨的雨1 小时前
Rust专项——其他集合类型详解:BTreeMap、VecDeque、BinaryHeap
开发语言·后端·rust
渡我白衣1 小时前
C++世界的混沌边界:undefined_behavior
java·开发语言·c++·人工智能·深度学习·语言模型
剑海风云2 小时前
JDK 26:HTTP/3 支持已可在 HTTP 客户端 API 中使用
java·开发语言·http
下一站丶2 小时前
【JavaScript性能优化实战】
开发语言·javascript·性能优化
GIS好难学2 小时前
Three.js 粒子特效实战③:粒子重组效果
开发语言·前端·javascript