软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键。这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是要重点测试版本的性能表现和稳定性的。对于软件测试过程中发现的性能问题,如何定位有很多的方法。基本的方法可能是开发者对代码进行review
,或者是使用一些工具对代码进行性能分析。常见的性能分析工具有哪些呢?以下两篇文章做了详细的总结:
- https://computing.llnl.gov/tutorials/performance_tools/#Considerations
- http://en.wikipedia.org/wiki/List_of_performance_analysis_tools
gprof
是可用于Linux C++
代码性能分析工具之一。
gprof
的基本原理
gprof
能够让你知道你的代码哪些地方是比较耗时的,哪些函数是被调用次数很多的,并且能够让你一目了然的看到函数与函数之间的调用关系。gprof
是gcc/g++
编译器支持的一种性能诊断工具。只要在编译时加上-pg
选项,编译器就会在编译程序时在每个函数的开头加一个mcount
函数调用,在每一个函数调用之前都会先调用这个mcount
函数,在mcount
中会保存函数的调用关系图和函数的调用时间和被调次数等信息。最终在程序退出时保存在gmon.out
文件中,需要注意的是程序必须是正常退出或者通过exit
调用退出,因为只有在exit()
被调用时才会触发程序写gmon.out
文件。
那么,gprof
的使用方法主要以下三步:
- 使用
-pg
参数编译程序 - 运行程序,并正常退出
- 查看
gmon.out
文件
gprof
使用实例
使用g++
编译并加上-pg
参数:
得到可执行文件,我们可以使用readelf
查看一下它的符号表里和没有-pg
参数编译的区别。
和
得出的结果对比如下图:
左边为有-pg
参数编译的结果。可以看出多了三个函数符号_mcount
, __monstartup
, _mcleanup
都是和gprof
相关的调用。
接下来运行程序
会在当前目录下生成gmon.out
文件。
使用gprof
查看文件信息:
得到如下输出:
可以使用运行命令:
生成dot
格式的调用关系图文件,可以使用Windows
版的GVEdit for Graphviz
软件查看调用关系图:
对于Ubuntu 16.04
系统来说,可以执行如下命令生成调用关系图
附上一张比较复杂的程序调用关系图(需要放大来看):
对于调用的关系和调用热点一目了然。
gprof
输出解读
这部分内容可将gprof -b ./hello
中的-b
参数去掉,可以显示字段的详细含义描述:
总结
gprof
是常见的性能分析工具,在此罗列一下它的一些不足,也是从网上看的:
- 对多线程支持不好,不准确
- 必须是调用
exit()
退出进程才行,也就是进程需要自然结束 - 它只能分析应用程序在运行过程中所消耗掉的用户时间,无法得到程序内核空间的运行时间。对内核态的调用分析无能为力。