在软件开发过程中,性能优化是不可或缺的一部分。无论是在Web服务、数据处理系统还是实时通信中,良好的性能都是至关重要的。Golang 从1.20版版本开始引入的 Profile Guided Optimization(PGO)机制能够帮助更好地优化 Go 程序的性能。
上篇文章详细讲解了收集有效样本数据和编译方面的知识,本文详细讲解一下大家可能会对 PGO 产生的疑问。
PGO 优化对 Golang 标准库中的包有效吗?
答案是肯定的,PGO 对整个应用程序都有效,所有包都会基于 PGO 文件被重新编译,包括标准库中的包。
PGO 优化对依赖模块中的包有效吗?
答案是肯定的,PGO 对整个应用程序都有效,所有包都会基于 PGO 文件被重新编译,包括依赖模块中的包。所以,对依赖模块的特殊的用法会影响优化效果。
如果采用的 PGO 配置文件不能反映出典型的使用场景,使用 PGO 优化后的程序性能会更差吗?
应该不会。不能反映典型使用场景的 PGO 配置文件会对应用程序中不会被频繁运行的那部分逻辑代码进行优化,但并不会使频繁被运行的那部分代码的性能降低。
如果应用程序要构建出针对不同操作系统、不同系统架构的版本,能使用同一份 PGO 配置文件吗?
答案是可以的,针对不同操作系统和不同系统架构的版本,配置文件的格式都是相同的。例如,从 linux/arm64 系统上收集的样本文件可以在针对 windows/amd64 系统的构建过程中使用。
开启 PGO 会影响构建时间吗?
启用 PGO 后可能会导致构建时间的显著增加。因为 PGO 会对所有包有效,所以首次使用 PGO 时,每个包都会重新构建。因为这些构建也会被缓存,所以后续使用相同的 PGO 配置文件进行增量构建时不需要完全重新编译。
开启 PGO 如何影响构建出的二进制文件的大小?
由于额外的函数内联,开启 PGO 侯建出的二进制文件会稍大一点。
Go 1.21中关于 PGO 的改进
PGO 从 Go 1.20版本作为实验性的功能被引入,编译的时候需要通过指定 pgo 参数才会生效,例如 -pgo=auto 或者 -pgo=auto=xxx.pprof 来开启。从 Go 1.21开始,pgo 转为了正式功能,go build 会自动检测程序主目录下是否存在 default.pgo 文件,如果检测到则启用 PGO 来构建。
关于 PGO 对性能的提升情况,Golang 官方给出的数据是,在 Go 1.21中,一组具有代表性的 Go 程序的基准测试表明,使用 PGO 构建可以提高大约2-7%的性能。随着 Golang 对 PGO 的不断优化和收集的 PGO 配置文件的代表性不断提高,PGO 对性能的提升作用相信也会越来越大。