我有一个我正在尝试分析的 Go 二进制文件,我得到了令人惊讶的结果。该代码在 中具有以下(截断)main.go
,其余代码在包中monte
:
package main
import (
"monte"
"runtime/pprof"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
}
monte.ExpensiveOperation()
pprof.StopCPUProfile()
}
我用 构建我的可执行文件go build src/main.go
,然后用./main -cpuprofile=monte.prof
. 当我检查输出时go tool pprof main monte.prof
,我得到以下输出:
(pprof) top10 --cum
Total: 346 samples
280 80.9% 80.9% 343 99.1% time.Time.Format
0 0.0% 80.9% 341 98.6% runtime.interhash
0 0.0% 80.9% 341 98.6% runtime.main
0 0.0% 80.9% 251 72.5% strconv.Unquote
13 3.8% 84.7% 31 9.0% strconv.roundShortest
11 3.2% 87.9% 18 5.2% strconv.fmtE
9 2.6% 90.5% 9 2.6% runtime.markallocated
1 0.3% 90.8% 8 2.3% math/rand.Float64
2 0.6% 91.3% 8 2.3% runtime.FixAlloc_Free
7 2.0% 93.4% 8 2.3% time.nextStdChunk
累积时间最长的函数是time.Time.Format
,这对我来说似乎是错误的(不应该是main
吗?)并且根本没有提及monte
,尽管“昂贵的操作”需要大约 10 秒才能完成,时间充裕让采样器看到它。如果我将--focus=monte
标志传递给go tool pprof
,则根本不会显示任何样本。我假设我在某处遗漏了一些标志;有人有什么想法吗?谢谢!