最近在整理以前攢的 go 語言學習資料 -- 可能很多人都和我一樣, 隨手一個收藏, 不動手也不深入, 然後就過去了. 這次從故紙堆裏掃出來, 當然不能錯過
資料:
- blog 地址: https://www.cnblogs.com/sunsky303/p/9296188.html
- 原作者已經提供好了代碼: https://github.com/Deleplace/forks-golang-good-code-bad-code
學習到的知識:
- 使用
go test
進行 單測/壓測 - 使用
go tool
進行 prof/trace - 性能問題 debug 與優化思路
let's party
作者準備好了代碼 https://github.com/Deleplace/forks-golang-good-code-bad-code
確定基準, 使用 cpuprof 中的
ns/op
作爲比較基準
cd bad
➜ bad git:(master) ✗ go test -bench=. -cpuprofile cpu.prof
goos: darwin
goarch: amd64
pkg: test/bad
BenchmarkParseAdexpMessage-8 18999 63848 ns/op
PASS
ok test/bad 2.007s
bad & good 代碼對比: good 更慣用,更易讀,利用go語言的細節, 後續的修改都基於 good 代碼進行
查看 trace, 查看 CPU 使用情況
# 使用 trace 工具
go test -bench=. -trace trace.out
go tool trace trace.out # 會在默認瀏覽器中打開 trace
trace 分析: 放大 CPU 部分 -> 數千個小的彩色計算切片 + 空閒插槽 -> 一些核心處於空閒狀態
首先進行競爭檢測, 如果發生競爭, 比性能問題更嚴重
# 競爭檢測
go test -race
// 改動就一行
for _, line := range in {
// go mapLine(line, ch)
mapLine(line, ch)
}
- 使用 cpuprof, 查看熱函數調用, 定位到瓶頸
# 1. 生成 cpuprof
go test -bench=. -cpuprofile cpu.prof
# 2. 生成 svg
go tool pprof -svg cpu.prof > cpu.svg
# 3. 使用 chrome 打開 svg 文件即可
-
根據瓶頸進行性能優化: https://github.com/Deleplace/forks-golang-good-code-bad-code/tree/performance
- Fast custom trim func, to remove the space character only.
- Use bytes.HasPrefix.
- regexp.MustCompile is exactly what we need here.
- Instead of regexp, use a loop: 10x speedupgap .
- bytes.IndexByte is more appropriate here.
- Small parseLine and findSubfields refactoring, same perf.
- Remove startWith, call directly bytes.HasPrefix: slightly faster.
-
協程使用(調度)優化: 5k message + 20/100 協程
到此, 已經優化達到的效果
- 還能不能再過分一點: 能, 用
Lexer + Parser
https://github.com/Deleplace/forks-golang-good-code-bad-code/tree/lexerparser
寫在最後
總算把一個很久很久之前的坑給填上了, 開心😺
- prof 相關: 可以定位熱點函數, 方便定位瓶頸
go test -bench=. -cpuprofile cpu.prof # 壓測, 生成 prof 文件
go tool pprof -svg cpu.prof > cpu.svg # 使用 prof 工具, prof 轉爲 svg, svg 可以使用 chrome 打開
- trace 相關: 可以查看 cpu 使用狀態
go test -bench=. -trace trace.out
go tool trace trace.out
- goroutine 相關
首先要區分 CPU密集型任務/IO密集型任務, 協程更適合處理 IO密集型任務, 減少 IO wait 導致的 CPU 空轉, 其次協程過多會導致協程調度的開銷, 同樣會造成性能損失
- 推薦使用 github desktop
切換分支, 查看 commit, so easy ~