代码性能分析-Dottrace跟踪代码执行时间

当自己程序遇到性能问题,比如请求反应缓慢,怎么分析是哪里出了问题呢?dottrace可以帮助.net程序跟踪出代码里每个方法的执行时间,这样让我们更清晰的看出是哪里执行时间过长,然后再分析应该怎样解决。

Dottrace是由JetBrainshttp://www.jetbrains.com/ 公司开发的一款产品,它分dottrace Performancedottrace Memory 两个工具,dottrace Performance用来分析代码性能,比如函数执行时间,调用次数,消耗时间比率等,dottrace Memory一般用来分析内存占用情况。

本篇文章介绍dottrace跟踪代码执行时间来分析性能问题,因此用到的是dottrace Performance工具。它可以跟踪.net编写的:应用程序,IIS挂接的程序,windows服务,silverlightWCF服务程序等。还可以把跟踪的文件,以快照的方式保存下来,保存为dtp后缀的文件。跟踪后的结果,如果能找到对应用户的代码信息,还可以直接查看对应的源代码,并选择在VS里直接编辑该方法对应的文件。

 

1.Hot Spots视图。这个视图根据耗时从大到小排序了所有的方法。我们可以马上发现耗时最长的方法。总共有两种情况:

            1.1该方法被调用次数非常少,但是非常耗时。这时马上得出结论,该方法就是性能瓶颈。记录下来,分析代码。

            1.2该方法被调用次数很多。此时就需要使用另一个视图:Back Trees

      2.Back Trees视图。这个视图通常是用来分析一个被调用很多次的函数的Callee,因为一般来说,一个函数被调用多次,一般是在某一个Callee中有一个循环或者递归 ,而性能调优的入口是这个Callee函数,而不是被调用者本身。(其实Hot Spots本身也是Back Tree,只是我们可以单独把一个函数在一个Tab页中开打,然后使用Back Tree单独分析)

      3.Plain List视图。有时候,我们会发现,在Hot Spots里会出现很多系统函数,比方Linq的操作,这时如果函数太多,也许对定位不方便。这时可以使用 Plan List 视图,它只显示过滤以后的函数,然后根据Own Time进行排序,找出耗时最长的函数。但是,如果一个耗时的函数都没发现,就很有可能是由于资源的操作导致性能下降,比如循环调用Linq操作,或者发送邮件一直等待等原因。

      4.Call Tree视图。在dotTrace中,Call Tree中的每一个函数的子函数并不是按照调用顺序来排列的,而是根据耗时百分比来排列的。(如果要查看函数的子函数执行顺序,在Plain List中查看)。这样的话我们可以快速的定位到下一个Important Call,并且dotTrace还提供了快捷键ctrl+shift+->(右箭头)。但是Call Tree视图对于分析有个不好的地方,就是某个函数也许会在不同的分支被循环调用,这时使用Call Tree是非常难发现的,这也是Back Tree存在的意义。

   补:我看到CSDN有朋友说,dotTace跟踪Windows From的程序发现子函数加起来的时间跟远小于父函数的时间,那是因为dotTrace的过滤功能, 只要点击百分数前面的小图标“unfold filtered calls”,就能把所有过滤掉的函数显示出来。实际上,该朋友碰到的情况是,dotTrace过滤掉了Application.Run()函数调用的消息循环函数RunMessageLoop。

下图为一个分析性能调优的一个例子:

 

从结果可以直接看出,整个页面加载了6.140秒,其中addPNRInforetrievePNR两个方法一共都占用了5.92秒,然后就可以根据这两个方法进行优化了。

 

现在讲下左侧Views目录下的5个视图栏:

Overview:这个可以看到该性能分析文件的抓取方式,比如上面例子为Line-by-line,Wall Time(CPU instruction)的方式,抓取的URL地址等,还会有该视图下的系统配置情况以及当前的模块以及方法个数等信息。

Threads Tree:记录当前每个线程执行的方法,以及方法的性能情况。

Call Tree:不管线程,按所有请求的入口为一条数据展现,但里面展现的排序是按照执行时间高低排序的,不是按照代码顺序展现的。

Plain List:展现所有非内核代码的方法列表,并展现每个方法执行时间和被调用次数。

Hot Spots:它会把所有代码包括内核代码的方法,按照执行时间排序顺序展现到列表,并记录每个方法的执行时间比率和时间等信息。

 

每次要进行性能分析,除了选择IIS还是应用程序等方式外,还要选择抓取的方式,一般的选择界面如下:

 

上面是选择抓取IIS Application程序后的选择界面,其中重要的是下面的Profiler options选项。

profiling type有下面三个选项:

Tracing:它是通过获取CLR内部一个方法开始执行和结束执行的时间差来计算的分析时间。

Line-by-line:它是通过收集代码执行的每条语句的时间来,它计算出的时间更精确。

Sampling:它是抽样的方式,每隔一段时间(windows下大概是10ms),会暂停所有线程,并抓取堆栈里的信息,然后计算出代码执行时间差,这个选项可能会导致一些执行很短的方法抓取不到的问题。

Measure有下面三个选项:

Wall time(performance counter) 它是通过Performance Counter API来收集的信息,一般操作系统和各个硬件设备都提供性能计数的API供程序调用。

Thread time:它只支持Sampling的分析方式,它通过一个固定的线程来抓取堆栈信息计算时间,并且它只计算自己内部程序执行的时间,不管等待其他IO的时间。

Wall time(CPU instruction):它是通过读取TSC processor register里记录的方法进入和退出时间差的方式来计算的。

 

根据上面的选项方式,一般我们要想完整分析自己程序的执行时间,建议可以采用Line-byline(Tracing)Wall time(CPU instruction)Wall time(performance counter)的方式,因为如果用抽样和Thread time的搭配方式,会只计算自己内部时间,不能计算自己程序和外部程序交互的时间,会让自己分析性能时产生误导。

在开始分析IIS挂接的网站性能问题时,用工具的File->Profile…会造成IIS应用程序池重启,可能时间会比较长,因为内部会预编译和比如操作数据库,没有开启数据库连接池,会影响分析的结果,误导自己以为数据库或内核代码导致性能问题。一般应该在第一次性能分析后,重新用Start Profiling的方式来重新测试网站数据,如图:

 

         内部会有很多内核代码和初始化的操作会影响性能分析,这里从新点击Start Profiling重新进行性能分析,它不会重启应用程序池,如图:

  

        

这样就减少了很多初始化的耗时操作,可以更精确的对性能进行分析了。

posted @ 2013-01-09 17:04  超级塞亚人  阅读(413)  评论(0)    收藏  举报