在确保代码运行正确无误之后,我们往往都需要进行性能优化,不过受限于阿姆达尔定律,性能优化需要针对热点代码进行。热点代码可以通过分析算法复杂度获得,也可以通过运行性能分析工具获得。在此我们给大家介绍一组工具callgrind+gprof2dot+dot,可以非常方便地分析代码瓶颈。

1.Callgrind

Valgrind是一款常用的代码分析工具,在大多数情况下我们都会用它来帮我们查找内存泄露和内存读写错误,但实际上,它的功能远不止如此。利用它的callgrind工具我们还可以对代码各部分的运行时间进行分析。使用方法如下:

valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./your_command

2.gprof2dot

上述命令会生成一个callgrind.out的性能分析文件,不过该文件不容易直接读懂,我们可以利用gprof2dot.py脚本将其转换成可以可视化的dot格式,进而利用dot命令生成图片。该脚本的使用方法很简单,基本命令如下:

python gprof2dot.py -f callgrind -n 0.5 -e 0.5 -s callgrind.out >perf.dot

简单描述就是它会分析callgrind的输出文件,并将输出结果重定向到dot格式的文件中。具体的用法我们把官网上的描述翻译一下。

2.1 命令行选项

选项 含义
-o FILE, --output=FILE 指定输出文件,默认是标准输出(也即屏幕),还可以通过重定向来实现该选项
-n PERCENTAGE, --node-thres=PERCENTAGE 运行时间占比小于PERCENTAGE的节点(函数调用)不展示(默认阈值是0.5)
-e PERCENTAGE, --edge-thres=PERCENTAGE 作用和上面类似,对边进行剪枝
-f FORMAT, --format=FORMAT 性能分析日志的来源,支持的来源有:axe, callgrind, hprof, json, oprofile, perf, prof, pstats, sleepy, sysprof, xperf。该脚本支持多种性能分析工具,默认是prof,我们采用的是callgrind分析工具。
–total=TOTALMETHOD 采用哪种方法统计总时间:callratios 或者 callstacks(只对perf分析工具有作用),默认是callratios 。
-c THEME, --colormap=THEME 颜色主题:color, pink, gray, bw,默认是color,效果也最好。
-s, --strip 不显示函数参数、模版参数、常量修饰符等对展示无影响的符号,启用该选项会让生成的图片更直观易懂,一般启用。
-w, --wrap 当函数名过长的时候自动换行,启用会让生成的图片更美观
–show-samples 展示function samples?
-z ROOT, --root=ROOT 只展示ROOT函数及其子孙调用关系,忽略其他调用,当函数调用关系复杂只分析某一部分函数的调用关系时非常有用。
-l LEAF, --leaf=LEAF 只展示某个函数及其父亲调用关系,忽略其他调用。
–skew=THEME_SKEW 调整节点颜色的区分度。值<1区分度更明显,否则更不明显。建议用默认值,或者<1的值。

2.2 节点格式

输出图片中的每个节点展示一个函数调用的详细信息,具体格式如下:

function name
total time % ( self time % )
total calls

其中,total time表示该函数在总运行时间中的占比,self time表示该函数除去可显示的子函数时间之后剩余的时间占比,total calls表示该函数被调用的次数(包括递归调用)。每条边展示的是子节点的时间占比和调用次数。

2.3 FAQ

  1. 如何生成一个完整的调用图?
    默认情况下,gprof2dot脚本会忽略时间占比非常小的函数,导致生成的调用图不全。如果想统计所有函数的调用关系和时间占比,我们可以将-n和-e的阈值设置为0。
  2. 节点的函数名太长,怎么让它变窄?
    默认情况下,函数名会包括作用域,参数和模版参数等,导致函数名特别长。我们可以通过-s选项去掉这些信息,也可以通过-w命令将其换行。
  3. 脚本生成的图片为空,或者所有节点都是相同的颜色,时间占比加和不一致?
    当程序执行时间很短时,脚本无法获取足够的信息来确定各函数的执行时间导致图片为空或者时间占比加和不一致。所以使用gprof2dot的前提是程序要运行比较长的时间,这样才能获取比较准确的函数调用图。
  4. 编译时应该传递什么编译选项?
    为了生成比较准确的性能分析结果,必须要传递下面两个选项:
  • -g:产生debug信息
  • -fno-omit-frame-pointer:使用frame pointer(frame pointer usage is disabled by default in some architectures like x86_64 and for some optimization levels; it is impossible to walk the call stack without it)
    如果使用的性能分析工具是gprof,我们还需要添加-pg选项。
    如果希望分析结果和release版很接近,我们还需要添加如下两个选项:
  • -O2:初步优化
  • -DNDEBUG:禁掉标准库中的debug代码(例如assert宏)
    在很多情况下,启用代码优化之后会导致很多函数被展开,使得性能分析工具不准确,我们可以添加选项避免函数内联展开:
  • -fno-inline-functions:不要将函数展开到父函数中,这样函数计时都会归到父函数中;
  • -fno-inline-functions-called-once:和上面类似
  • -fno-optimize-sibling-calls:do not optimize sibling and tail recursive calls (otherwise tail calls may be attributed to the parent function)
    在开启比较高等级优化的情况下,有些函数即使没有加inline关键字,编译器也会自动给你展开成内联函数,可以通过下面两个选项关闭自动内联:
  • -fno-default-inline:do not make member functions inline by default merely because they are defined inside the class scope
  • -fno-inline:do not pay attention to the inline keyword Note however that with these last options the timings of functions called many times will be distorted due to the function call overhead. This is particularly true for typical C++ code which expects that these optimizations to be done for decent performance.

3.dot

dot命令是graphviz的一部分,通过编写一些类似脚本的语言,可以容易地生成流程图,其输出格式包括PostScript,PDF,SVG,PNG,含注解的文本等等,在fedora系统上可以通过yum install graphviz安装。在此我们不关注dot脚本的格式及其编写,只关心将gprof2dot生成的dot文件转换成图片进行可视化。
格式:dot -T -o <infile.dot>
输入文件是<infile.dot>,生成的格式由指定,生成的文件是。针对前面生成的perf.dot文件,我们可以通过命令dot -Tpng perf.odt -o perf.png来生成png格式的图片。另外我们也可以利用管道将上述命令组合在一起:

python gprof2dot.py -f callgrind -n 0.5 -e 0.5 -s callgrind.out | dot -Tpng -o perf.png

下面是一张用上述三个命令组合生成的一个性能分析图,从该图我们可以很清晰地看出每个函数的时间占比:

利用callgrind+gprof2dot+dot进行性能分析相关推荐

  1. 【Java VisualVM】使用 VisualVM 进行性能分析及调优

    转载:https://blog.csdn.net/lmb55/article/details/79267277 一.概述 开发大型 Java 应用程序的过程中难免遇到内存泄露.性能瓶颈等问题,比如文件 ...

  2. 使用 VisualVM 进行性能分析及调优

    2019独角兽企业重金招聘Python工程师标准>>> 概述 开发大型 Java 应用程序的过程中难免遇到内存泄露.性能瓶颈等问题,比如文件.网络.数据库的连接未释放,未优化的算法等 ...

  3. 深入理解 Java 虚拟机-如何利用 VisualVM 对高并发项目进行性能分析

    来自:好好学java 前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使用IDEA,而VisualVM对于IDEA也不错,所以就选择Visua ...

  4. 深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析

    Java虚拟机深入理解系列全部文章更新中- 深入理解Java虚拟机-Java内存区域透彻分析 深入理解Java虚拟机-常用vm参数分析 深入理解Java虚拟机-JVM内存分配与回收策略原理,从此告别J ...

  5. idea 优化_JVM优化:如何利用VisualVM对高并发项目进行性能分析

    前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使用IDEA,而VisualVM对于IDEA也不错,所以就选择VisualVM来分析JVM性能 ...

  6. 利用chromeDevTools的Performance面板进行性能分析调优

    Chrome DevTools之Performance Chrome DevTools中Performance面板可以帮助我们进行性能分析,使我们写出更加精悍的代码. 下面是一段简单的代码. var ...

  7. 使用golang pprof进行性能分析

    golang pprof,说实话自己还一次都没有实际操作过. 最近这几天的需求恰好需要分析下一个看似很简单的服务,内存配置上限是900m,最终在大量并发的时候出现oom的情况. 代码准备 首先代码需要 ...

  8. Android 应用进行性能分析/APP/系统性能分析

    如何对 Android 应用进行性能分析 记录一下自己在使用DDMS的过程:开启AS,打开并运行项目  找到TOOL/选择Android Device Monitor 一款 App 流畅与否安装在自己 ...

  9. linux c++ 函数效率,Linux C++程序进行性能分析工具gprof使用入门

    性能分析工具 软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键.这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是 ...

  10. Android:通过systrace进行性能分析及使用-详细

    Android:通过systrace进行性能分析 https://www.cnblogs.com/blogs-of-lxl/p/10926824.html 一.Systrace 简介 Systrace ...

最新文章

  1. KubeShere安装Redis
  2. python调用自定义函数返回值的类型_生成dll文件以及python对DLL中函数的调用(参数类型以及返回值)...
  3. 因为阿里,他们成了“杭漂”
  4. LVM---逻辑盘卷管理
  5. 飞行模式的开启和关闭
  6. 子弹创建及发射 Learn Unreal Engine (with C++)
  7. 计算机寄存器端口,CPU和外设之间的数据传送方式有哪几种
  8. “东数西算”,全国一体化算力网络八大枢纽节点批复函+图解
  9. 对extern C的一点小认识
  10. oracle em搭建,【oracle】手动安装EM
  11. ajax上送src,使用script的src实现跨域和类似ajax效果
  12. 用PHP的GD库绘制弧形图像
  13. 读者问题:3种解决办法伪代码
  14. [debug] you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake ……
  15. 【多模态】来自Facebook AI的多任务多模态的统一Transformer:向更通用的智能迈出了一步...
  16. http://snaps.php.net,科技常识:Windows下编译PHP和memcache扩展教程
  17. JDK中的SPI和Spring中的SPI
  18. 交换机的作用是什么?交换机功能及工作原理详解!
  19. 微软苏州集体抵制来自阿里、华为的跳槽者:请停止你的“奋斗逼”行为!
  20. 微信如何群删好友 微信群删好友的方法教程

热门文章

  1. 金融网络安全和反欺诈方法论,金融新兴技术成熟度几何?
  2. python中turtle画小草_python 笔记 之带参数的装饰器
  3. 悼念王选:伟大发明家和失意企业家间的孤独者
  4. Mysql之to_base64编码from_base64解密和AES_ENCRYPT加密AES_DECRYPT解密
  5. 巨杉数据库SequoiaDB协调节点
  6. 什么是京东自营商品?京东自营是什么意思?京东自营?
  7. 计算机视觉基础知识:射影变换,仿射变换,相似变换(比例变换),刚性变换
  8. 'E:\AndroidSDK\platform-tools\adb.exe start-server' failed -- run manually if necessary
  9. 2015年总结,平平淡淡的一年.
  10. 2016年计划,2015年总结