Go 学习笔记(81)— Go 性能分析工具 pprof
Go 語言工具鏈中的 go pprof 可以幫助開發(fā)者快速分析及定位各種性能問題,如 CPU消耗 、內(nèi)存分配及阻塞分析 。具體作用如下:
性能分析首先需要使用 runtime.pprof 包嵌入到待分析程序的入口和結(jié)束處 。runtime.pprof 包在運(yùn)行時(shí)對(duì)程序進(jìn)行每秒 100 次的采樣,最少采樣 1 秒。然后將生成的數(shù)據(jù)輸出 , 讓開發(fā)者寫入文件或者其他媒介上進(jìn)行分析。
go pprof 工具鏈配合 Graphviz 圖形化工具可以將 runtime.pprof 包生成的數(shù)據(jù)轉(zhuǎn)換為 PDF格式,以圖片的方式展示程序的性能分析結(jié)果 。
1. 安裝 Graphviz
Graphviz 是一套通過文本描述的方法生成圖形的工具包。描述文本的語言叫做 DOT 。在 www.graphviz.org 網(wǎng)站可以獲取到最新的 Graphviz 各平臺(tái)的安裝包 。
CentOS下,可以使用 yum 指令直接安裝 :
yum install graphviz
Ubuntu 下
sudo apt-get install graphviz
其它平臺(tái)安裝方式可參考: https://www.graphviz.org/download/
2. 安裝第三方包
runtime.pprof 提供基礎(chǔ)的運(yùn)行時(shí)分析的驅(qū)動(dòng),但是這套接口使用起來還不是太方便,例如:
- 輸出數(shù)據(jù)使用
io.Writer接口,雖然擴(kuò)展性很強(qiáng), 但是對(duì)于實(shí)際使用不夠方便,不支持寫入文件; - 默認(rèn)配置項(xiàng)較為復(fù)雜;
很多第三方的包在系統(tǒng)包 runtime.pprof 的技術(shù)上進(jìn)行便利性封裝,讓整個(gè)測試過程更為方便。這里使用 github.com/pkg/profile 包進(jìn)行例子展示,使用下面代碼安裝這個(gè)包:
go get github.com/pkg/profile
3. 性能分析示例
cpu.go 代碼內(nèi)容:
package mainimport ("time""github.com/pkg/profile"
)func joinSlice() []string {var arr []string// 為了進(jìn)行性能分析,這里在己知元素大小的情況下,還是使用 append()// 函數(shù)不斷地添加切片。性能較低,在實(shí)際中應(yīng)該避免,這里為了性能分析,故意這樣寫。for i := 0; i < 1000000; i++ {arr = append(arr, "arr")}return arr
}func main() {// 開始性能分析, Start 參數(shù)都是可選項(xiàng),指定的分析項(xiàng)目是profile.CPUProfile// profile.ProfilePath(".") 指定輸出的分析文件路徑,// profile.Start 返回一個(gè)停止接口stopper := profile.Start(profile.CPUProfile, profile.ProfilePath("."))// 在main結(jié)束時(shí)停止性能分析defer stopper.Stop()// 分析的核心邏輯joinSlice()// 為了保證性能分析數(shù)據(jù)的合理性,分析的最短時(shí)間是 1 秒,使用 time.Sleep()// 在程序結(jié)束前等待 1 秒。如果你的程序默認(rèn)可以運(yùn)行 1 秒以上,這個(gè)等待可以去掉 。time.Sleep(time.Second)
}
性能分析需要可執(zhí)行配合才能生成分析結(jié)果,因此使用命令行對(duì)程序進(jìn)行編譯,步驟如下:
go build -o cpu cpu.go
./cpu # 運(yùn)行可執(zhí)行文件,在當(dāng)前目錄下生成 cpu.pprof
go tool pprof --pdf cpu cpu.pprof > cpu.pdf
使用 go tool 工具鏈輸入 cpu.pprof 和 cpu 可執(zhí)行文件,生成 PDF 格式的輸出文件,將輸出文件重定向?yàn)?cpu.pdf 文件。這個(gè)過程中會(huì)調(diào)用 Graphviz 工具。
?
4. PDF 結(jié)果
每一個(gè)框?yàn)橐粋€(gè)函數(shù)調(diào)用的路徑,第 3 個(gè)方框中 joinSlice 函數(shù)耗費(fèi)了 76% 的 CPU 時(shí)間,存在性能瓶頸。
重新優(yōu)化代碼, 在己知切片元素?cái)?shù)量的情況下直接分配內(nèi)存,代碼如下:
func joinSlice() []string {const count = 1000000var arr = make([]string, count)for i := 0; i < count; i++ {arr[i] = "arr"}return arr
}
5. 實(shí)戰(zhàn)案例
https://github.com/wolfogre/go-pprof-practice
https://blog.wolfogre.com/posts/go-ppof-practice/
總結(jié)
以上是生活随笔為你收集整理的Go 学习笔记(81)— Go 性能分析工具 pprof的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: perl: warning: Setti
- 下一篇: 2022-2028年中国汽车铝合金冲压件