最近要对推送程序进行性能优化,找出程序的hot spots,程序是用VS2005,C++写的,因此直接使用VS2005自带的性能分析工具对程序作了一次profiling。数据库
使用VS2005打开工程,在菜单“工具”下面有个“性能工具”的选项,点击右边的“性能向导”就能够开始新建一个性能测试项了。 如: 若是点击菜单没有看到上图的“性能工具”选项,说明安装时候没有选择安装测试工具,请到“控制面板”->“添加删除程序”里面进入VS2005的维护模式,将“team development和team test工具”选上。如图:
从新安装VS2005,重启VS2005便可。缓存
有两种:采样和检测。性能优化
对于一个Profiler来讲,给程序带来负担(overhead)是难以免的。通常来讲,Profiler都会提供多种探测方式,例如采样(Sampling)或是追踪(Tracing)。“采样”通常都是定时打点,看看程序每一个线程当前落在哪一个方法里,当前的调用堆栈是什么,以此发现程序热点,“追踪”则每每会记录方法进入和退出的时间,因此显然前者的负担要小事后者。赵人希的微信微信
“检测”应该就是赵人希所说的“追踪”方式。本次测试开始用“采样”方式,可是运行时报错,因此最终使用了“检测”方式。异步
经过向导很是简单的创建了测试项以后就会出现“性能资源管理器”。设好参数,点击开始。程序就跑起来了。这跟普通的调试程序编译运行没啥两样。在此过程当中,测试程序不断的给被测程序发请求,增长压力,以便较好的模拟程序真实的使用场景。压了10多分钟吧,估计差很少了,退出被测程序,VS就开始生成性能分析报告,此过程甚是漫长,估计快弄了20分钟左右。看来咱们的推送程序仍是作了很多工做。接下去就能够看到分析结果了。函数
对于测试结果的查看能够参考MSDN上的介绍。 具体到本次测试程序,结果以下: 从最多调用次数看:因为函数名都是C++连接以后的名字,函数名部分被改写没法识别,猜想前两个是基本的stl的字符串比较和赋值等操做,第三个是memset,调用次数最多但不必定是最耗时的瓶颈。 耗时最长分别为wait(ACE线程等待函数)、伊诺收包的回调函数OnRecvRequest和伊诺的定时器OnTimer函数。估计wait函数是阻塞的,一直都在wait不耗CPU?反正这个目前也不在个人控制范围以内,先无论;伊诺的OnRecvRequest和OnTimer函数是直接调用的TCClient.dll。无代码也不能控制。囧oz。 接下去的几个tab主要展现的几列为:总调用次数、函数自己调用所用时间(不包括函数中调用其余函数的时间。只是自己的耗时)简称“净时间”、略、函数调用所用的时间(包括函数调用中调用其余函数的时间)简称“总时间”、略 经过净时间和总时间的关系、函数调用树的关系能够找到程序的热点——哪一个函数比较耗时。 首先,耗时的函数其总时间与净时间之差应该很小,一眼看去应该是基本相等的。 其次,对总时间排序,经过函数调用关系树,逐级查看,最终找到合适粒度的耗时函数。
memset的调用最多。与代码中把C++当C用、满眼所见都是memset十分吻合。但也能够看出memset虽然用的不少,但因为其效率很高,总的耗费时间并不高。工具
ACE队里的dequeue函数在队列为空时会阻塞。经过函数调用关系tree发现最终调用花费的时间都用在了wait函数上。 以Process函数为例,逐级查看下去,最耗时的操做在函数MsgReqProc1中,其最耗时的操做均为数据库操做。如图
性能
经过对总时间高的多个函数的追踪,综合查看能够发现,此程序最耗时的操做均是对数据库上的操做。后面对数据库的分析也印证了此结论。测试
从上面图中能够看出,全部涉及到数据库操做的耗时都是实打实的。并且增删查改的操做都是耗时的大户。能少用尽可能少用。并且ODBCDB.dll的总的净耗时比PubServ.dll的耗时高不少。也说明了其消耗了大量的时间。优化