标准库性能分析

标准库性能分析

runtime/pprof

首先进行 时间 - CPU 时间分析

import "github.com/pkg/profile"

func main() {
	defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
	// 想要进行分析的代码
}
time ./program

会生成 cpu.pprof 文件,程序的运行时间会加长,这是因为性能分析需要经常进行中断并记录有用的信息

go tool pprof
go tool pprof -http=:8080 cpu.pprof

如果出现 syscall.syscall 的时间占比比较大,可能是因为频繁的直接或间接地使用系统调用

红色箭头所指的流程是程序的瓶颈,如果发现线性执行代码的时间过长,应该考虑使用多协程(定长协程池)加快处理的速度,将单行处理准换成可扩展的并行处理,后续优化可以使用 trace 进行。优化时需要遵从多线程程序运行极限定理(Amdahl’s Law)

如果发现 mallocGC 这段比较耗时,说明存在内存方面的使用问题,可能涉及频繁分配内存,可进一步使用内存分配分析方法

空间 - Mem 内存分配分析

import "github.com/pkg/profile"

func main() {
	defer profile.Start(profile.MemProfile, profile.ProfilePath(".")).Stop()
	// 想要进行分析的代码
}

默认采样率为 4096 次分配采样一次

每次分配都采样

import "github.com/pkg/profile"

func main() {
	defer profile.Start(profile.MemProfile, profile.MemProfileRate(1), profile.ProfilePath(".")).Stop()
	// 想要进行分析的代码
}
go tool pprof
go tool pprof -http=:8080 mem.pprof

查看火焰图

打开 http://localhost:8080/ui/flamegraph 即可

net/http/pprof

Trace Tool

用来跟踪 GC 以及 goroutine 的调度以及运行情况

import "github.com/pkg/profile"

func main() {
	defer profile.Start(profile.TraceProfile, profile.ProfilePath(".")).Stop()
	// 想要进行分析的代码
}
go tool trace trace.out