Go语言性能调试方法

sh;;;;yd, Go
Back

Go 语言内置了性能调优的工具

一、准备工作

二、性能调优步骤和方法

示例代码:https://github.com/shiiiiyd/csgo/blob/main/tools/file/prof.go

1、build 程序

首先使用 go build prof.go 命令构建prof.go 文件,然后运行构建好的prof,使用 ls 命令可以查看到当前目录下会多出几个文件,包含:cpu.prof、goroutine.prof、mem.prof文件

2、使用pprof命令查看性能

查看CPU使用情况:

csgo/tools/file on  main [!+?] via 🐹 v1.17.12 took 2s 
❯ ls
cpu.prof       goroutine.prof mem.prof       prof           prof.go

csgo/tools/file on  main [!+?] via 🐹 v1.17.12 
❯ go tool pprof prof cpu.prof		## 进入pprof命令
File: prof
Type: cpu
Time: Jul 28, 2022 at 12:27pm (CST)
Duration: 907.52ms, Total samples = 760ms (83.74%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)
(pprof) top			## top 命令查看 cpu 性能
Showing nodes accounting for 760ms, 100% of 760ms total
Showing top 10 nodes out of 21
      flat  flat%   sum%        cum   cum%
     720ms 94.74% 94.74%      730ms 96.05%  main.fillMatrix
      20ms  2.63% 97.37%       20ms  2.63%  main.calculate (inline)
      10ms  1.32% 98.68%       10ms  1.32%  math/rand.(*rngSource).Int63
      10ms  1.32%   100%       10ms  1.32%  runtime.(*spanSet).pop
         0     0%   100%      760ms   100%  main.main
         0     0%   100%       10ms  1.32%  math/rand.(*Rand).Int31 (inline)
         0     0%   100%       10ms  1.32%  math/rand.(*Rand).Int31n
         0     0%   100%       10ms  1.32%  math/rand.(*Rand).Int63 (inline)
         0     0%   100%       10ms  1.32%  math/rand.(*Rand).Intn
         0     0%   100%       10ms  1.32%  os.Create (inline)
(pprof)
(pprof)
(pprof) list fillMatrix     ## 查看fillMatrix具体耗费时间的代码片段
Total: 760ms
ROUTINE ======================== main.fillMatrix in /Users/shiyd/go/src/github.com/csgo/tools/file/prof.go
     720ms      730ms (flat, cum) 96.05% of Total
         .          .     19:func fillMatrix(m *[row][col]int) {
         .          .     20:   s := rand.New(rand.NewSource(time.Now().UnixNano()))
         .          .     21:
         .          .     22:   for i := 0; i < row; i++ {
         .          .     23:           for j := 0; j < col; j++ {
     720ms      730ms     24:                   m[i][j] = s.Intn(100000)
         .          .     25:           }
         .          .     26:   }
         .          .     27:}
         .          .     28:
         .          .     29:func calculate(m *[row][col]int) {
(pprof) 
(pprof)

生成SVG图

## svg 命令是显示 graphviz 输出的svg文件,该文件是可以查看代码耗费的时间
(pprof) svg		
Generating report in profile001.svg
(pprof)exit

查看内存占用(mem)情况:

csgo/tools/file on  main [!+?] via 🐹 v1.17.12 
❯ go tool pprof prof mem.prof 
File: prof
Type: inuse_space
Time: Jul 28, 2022 at 12:27pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) 
(pprof) top
Showing nodes accounting for 3233.64kB, 100% of 3233.64kB total
Showing top 10 nodes out of 19
      flat  flat%   sum%        cum   cum%
 1184.27kB 36.62% 36.62%  1184.27kB 36.62%  runtime/pprof.StartCPUProfile
 1025.12kB 31.70% 68.33%  1025.12kB 31.70%  runtime.allocm
  512.20kB 15.84% 84.17%   512.20kB 15.84%  runtime.malg
  512.04kB 15.83%   100%   512.04kB 15.83%  runtime.bgscavenge
         0     0%   100%  1184.27kB 36.62%  main.main
         0     0%   100%  1184.27kB 36.62%  runtime.main
         0     0%   100%   512.56kB 15.85%  runtime.mcall
         0     0%   100%   512.56kB 15.85%  runtime.mstart
         0     0%   100%   512.56kB 15.85%  runtime.mstart0
         0     0%   100%   512.56kB 15.85%  runtime.mstart1
(pprof) 
(pprof) list main.main
Total: 3.16MB
ROUTINE ======================== main.main in /Users/shiyd/go/src/github.com/csgo/tools/file/prof.go
         0     1.16MB (flat, cum) 36.62% of Total
         .          .     41:   if err != nil {
         .          .     42:           log.Fatal("could not create CPU profile: ", err)
         .          .     43:   }
         .          .     44:
         .          .     45:   // 获取系统信息
         .     1.16MB     46:   if err := pprof.StartCPUProfile(f); err != nil { //监控cpu
         .          .     47:           log.Fatal("could not start CPU profile: ", err)
         .          .     48:   }
         .          .     49:   defer pprof.StopCPUProfile()
         .          .     50:
         .          .     51:   // 主逻辑区,进行一些简单的代码运算
(pprof) 
(pprof) 

3、使用 flame graphs 查看

go-torch 命令

使用go-torch cpu.prof 命令生成火焰图

❯ go-torch cpu.prof
INFO[10:03:05] Run pprof command: go tool pprof -raw -seconds 30 cpu.prof
INFO[10:03:05] Writing svg to torch.svg

三、通过HTTP方式输出Profile

上面的方式适用于非运行时的服务,如果是运行时的服务则可以通过HTTP访问的方式输出Profile 文件查看。

参考

[1]:https://pkg.go.dev/github.com/uber/go-torch@v0.0.0-20181107071353-86f327cc820e#section-readme

[2]:https://time.geekbang.org/course/detail/100024001-91253

[3]:https://ruanyifeng.com/blog/2017/09/flame-graph.html

[4]:https://blog.csdn.net/qq_17612199/article/details/80353355

© shiyd.RSS