C++程序性能分析

Wesley13
• 阅读 486

最近要对推送程序进行性能优化,找出程序的hot spots,程序是用VS2005,C++写的,所以直接使用VS2005自带的性能分析工具对程序做了一次profiling。

准备工作

使用VS2005打开工程,在菜单“工具”下面有个“性能工具”的选项,点击右边的“性能向导”就可以开始新建一个性能测试项了。 如: C++程序性能分析 如果点击菜单没有看到上图的“性能工具”选项,说明安装时候没有选择安装测试工具,请到“控制面板”->“添加删除程序”里面进入VS2005的维护模式,将“team development和team test工具”选上。如图: C++程序性能分析 重新安装VS2005,重启VS2005即可。

测试模式

有两种:采样和检测。

对于一个Profiler来说,给程序带来负担(overhead)是难以避免的。一般来说,Profiler都会提供多种探测方式,例如采样(Sampling)或是追踪(Tracing)。“采样”一般都是定时打点,看看程序每个线程当前落在哪个方法里,当前的调用堆栈是什么,以此发现程序热点,“追踪”则往往会记录方法进入和退出的时间,所以显然前者的负担要小过后者。赵人希的微信

“检测”应该就是赵人希所说的“追踪”方式。本次测试开始用“采样”方式,但是运行时报错,所以最终使用了“检测”方式。

测试过程

通过向导非常简单的建立了测试项之后就会出现“性能资源管理器”。设好参数,点击开始。程序就跑起来了。这跟普通的调试程序编译运行没啥两样。在此过程中,测试程序不断的给被测程序发请求,增加压力,以便较好的模拟程序真实的使用场景。压了10多分钟吧,估计差不多了,退出被测程序,VS就开始生成性能分析报告,此过程甚是漫长,估计快弄了20分钟左右。看来我们的推送程序还是做了不少工作。接下去就可以看到分析结果了。

测试结果

对于测试结果的查看可以参考MSDN上的介绍。 具体到本次测试程序,结果如下: C++程序性能分析 从最多调用次数看:由于函数名都是C++链接之后的名字,函数名部分被改写无法识别,猜测前两个是基本的stl的字符串比较和赋值等操作,第三个是memset,调用次数最多但不一定是最耗时的瓶颈。 耗时最长分别为wait(ACE线程等待函数)、伊诺收包的回调函数OnRecvRequest和伊诺的定时器OnTimer函数。估计wait函数是阻塞的,一直都在wait不耗CPU?反正这个目前也不在我的控制范围之内,先不管;伊诺的OnRecvRequest和OnTimer函数是直接调用的TCClient.dll。无代码也不能控制。囧oz。 接下去的几个tab主要展示的几列为:总调用次数、函数本身调用所用时间(不包括函数中调用其他函数的时间。只是本身的耗时)简称“净时间”、略、函数调用所用的时间(包括函数调用中调用其他函数的时间)简称“总时间”、略 通过净时间和总时间的关系、函数调用树的关系可以找到程序的热点——哪个函数比较耗时。 首先,耗时的函数其总时间与净时间之差应该很小,一眼看去应该是基本相等的。 其次,对总时间排序,通过函数调用关系树,逐级查看,最终找到合适粒度的耗时函数。 C++程序性能分析 memset的调用最多。与代码中把C++当C用、满眼所见都是memset十分吻合。但也可以看出memset虽然用的很多,但由于其效率很高,总的耗费时间并不高。

C++程序性能分析 ACE队里的dequeue函数在队列为空时会阻塞。通过函数调用关系tree发现最终调用花费的时间都用在了wait函数上。 以Process函数为例,逐级查看下去,最耗时的操作在函数MsgReqProc1中,其最耗时的操作均为数据库操作。如图C++程序性能分析

通过对总时间高的多个函数的追踪,综合查看可以发现,此程序最耗时的操作均是对数据库上的操作。后面对数据库的分析也印证了此结论。

C++程序性能分析 从上面图中可以看出,所有涉及到数据库操作的耗时都是实打实的。而且增删查改的操作都是耗时的大户。能少用尽量少用。而且ODBCDB.dll的总的净耗时比PubServ.dll的耗时高很多。也说明了其消耗了大量的时间。

优化方法

  1. 减少不必要的数据库操作。
  2. 对数据库采用异步、批量的操作方式,减少等待和阻塞。
  3. 多使用缓存。
  4. 优化数据库性能。如采用内存数据库、优化存储过程性能等。
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
分布式id如何生成
1.UUID生成通过网卡、时间、随机数来保证生成的唯一的字符串。优点:(1)本地生成,生成简单(2)速度快(3)高可用;缺点:(1)无序,如果存入mysq,影响B的操作性能,因为B树是需要排序的;(2)占用空间较大(36个
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
C# Aspose.Cells导出xlsx格式Excel,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
报错信息:最近打开下载的Excel,会报如下错误。(xls格式不受影响)!(https://oscimg.oschina.net/oscnet/2b6f0c8d7f97368d095d9f0c96bcb36d410.png)!(https://oscimg.oschina.net/oscnet/fe1a8000d00cec3c
Stella981 Stella981
3年前
Linux查看GPU信息和使用情况
1、Linux查看显卡信息:lspci|grepivga2、使用nvidiaGPU可以:lspci|grepinvidia!(https://oscimg.oschina.net/oscnet/36e7c7382fa9fe49068e7e5f8825bc67a17.png)前边的序号"00:0f.0"是显卡的代
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反