假如你对代码的性能要求比较高,这段对你应该有作用。在golang中的工具中有一个工具可以搜集cpu profile信息。具体使用方法:
在代码中引用runtime/pprof包即可。
//main.go
package main
import “runtime/pprof”
int main() {
f, err := os. Create("cpu.prof")
if err != nil {
// 可以输出一些出错信息
return
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// other code …
}
go build main.go
./main
执行后即可生成 cpu.prof文件在当前目录,其中记录了代码运行采样的信息。注意,你的代码切记不要太简单,因为pprof的采样是有频率是100次/秒,所以,如果你的代码运行时间过短(例如执行了1ms不到),很可能就采样不到数据(切记用time.Sleep延长执行结果是没有用的,因为我试过)。所以下面的步骤就没意义了。切记代码足够复杂,执行时间够长,仅仅写了个print是无法有结果的。
top命令
既然得到了profile文件,可以执行下面命令查看执行结果:
[tc01.tc Work test]$go tool pprof main cpu.prof
Welcome to pprof! For help, type 'help'.
(pprof)
在pprof工具中执行topN,例如:
(pprof)top10
会有如下显示
在显示结果中提一行:Total:1972 samples 是总采样数据。什么是采样,就是在代码在运行的时候,pprof会暂停程序,然后查看现在程序执行到那个函数中,方法是通过检查各个goroutine的堆栈信息,对堆栈中的所有函数进行计数。
下面讲一下各个字段的含义,最后一个字段是函数名,第一个字段是该函数的采样数量,第二个字段是这个函数的采样数量占总采样数量的百分比。第三个字段是百分比累加字段,第四个字段是在给函数中的采样数据,因为在采样过程时,程序停在了B函数,如果此时是A函数调用了B函数,那么A、B两个函数都会被记录。第五个字段自然是第四字段的百分占比。
list命令
也许你是一个非常认真地人,那么你一定想看的跟仔细一些,下面这个list命令可以让你看到,采样具体到哪行代码:
结果中的Index是函数名,这里查看的是Index函数中的采样结果,第一列是该函数的采样点,第二列是位于该函数的采样点和被该函数调用的函数采样点之和。例如第143行第一列没有数据是因为,此处的采样结果,只是在hashstr函数中有采样。
web命令
当然你会觉得上面不够直观,下面这个方法直接可以形成一个图片,你可以在浏览器中查看图片,不过首先你要在你的电脑中安装graphviz,这是一个库,用于生成图片。需要做的就是在pprof工具中执行web即可:
(pprof)web
得到的结果是:
结果中Loading web page file:////tmp/IwzpEzlPkp.0.svg说明了生成的文件在目录/tmp/中,名字就是IwzpEzlPkp.0.svg。当然,要保证你的磁盘时有空间的。后面的是Can’t的提示是因为没有浏览器能够启动起来查看该文件,所以忽略。要想查看,把该文件下载下来即可查看,我这里的的生成图是下面这样的。
总结
当然还有很多命令可以使用,不过这些命令已经足够你了解代码的性能了。其他相关命令你可以自己细细研究了。当然这里给你这些工具并不是让你看看就完事了,主要是为优化代码提供指导和依据。比如你看到代码在哪里采样比较多就说明那个地方执行的次数比较多或者是代码效率比较低,具体情况要分析代码了。有时候你发现map的频繁使用导致一个函数中的采样点大部分落在map操作上,我想如果可能,选择slice可能会是更好地选择。当然在make创建的时候,slice是比map耗时的,但是毕竟创建也就一次嘛。
有疑问加站长微信联系(非本文作者)