现代软件工程讲义 2 开发技术 - 效能分析

9.4  VSTS 效能分析工具程序员

啊,效能分析,Performance!这是每个程序员都梦想的事儿,让本身的程序跑得又快又好,最好是比别的同窗快一个数量级,别人的程序是O(N^2),而个人程序是O(n*logN),或者是O(N)这是多爽的一项成就呀!VSTS提供了方便的效能分析工具,让咱们能很快地找到程序的效能瓶颈,从而能有的放矢,改进程序。下面咱们看一个具体的例子。浏览器

和同窗们的做业相似,有这样一道题:app

写一个程序,分析一个文本文件中各个词出现的频率,而且把频率最高的10个词打印出来。框架

 

果冻很快用C#写好了程序,命名为WordFreq.exe,而后运行了一下,验证了正确性,程序的基本框架如代码清单9-3所示(所有程序能够在移山社区网站下载):ide

代码清单9-3  WordFreq程序,程序框架函数

DoIt()
{
    ProcessFile()  //store all words in a big buffer
    ProcessBuffer()  //calculate and store the frequency of each word
    OutputResult()   //output top 10
}
 
ProcessBuffer()
{
    GetOneWord()   //get one word from buffer
    FreqOneWord()
}
 
FreqOneWord(word)
{
Find the word in the array list,
If (found)
    Update the frequency
If (not found)
    Add the word in the array list with frequency = 1
}
 
OutputResult()
{
ArrayList.Sort()   //sort the array
Output Top 10 entry;
}

文本文件大约是30KB~300KB大小。在运行效能分析以前,阿超让你们预计占用时间最多的是什么函数,或者哪些语句。你们众说纷纭,有的说是处理文件,由于I/O很花时间,有的说是排序,有的说是处理每一个词。还有人建议应该把排序和处理每个词同时进行,这样就能加快速度。工具

咱们看看到底会是什么状况。第一步,要确保编译的程序是Release版本。而后在VS界面中选中Tools | Performance Tools | Performance Wizard(如图9-1所示)。测试

clip_p_w_picpath002

9-1  效能分析,选择分析方法网站

咱们看到能够选择两种分析方法:spa

(1)        抽样(Sampling

(2)        代码注入Instrumentation

通俗地解释,抽样就是当程序运行时,Visual Studio时不时看一看这个程序运行在哪个函数内,并记录下来,程序结束后,Visual Studio就会得出一个关于程序运行时间分布的大体的印象。这种方法的优势是不须要改动程序,运行较快,能够很快地找到瓶颈。可是不能得出精确的数据,代码中的调用关系(CallTree)也不能准确表示。

另外一方面,代码注入就是将检测的代码加入到每个函数中,这样程序的一举一动都被记录在案,程序的各个效能数据均可以被精准地测量。这一方法的缺点是程序的运行时间会大大加长,还会产生很大的数据文件,数据分析的时间也相应增长。同时,注入的代码也影响了程序真实的运行状况(这有点像量子物理学中的“测试的光线干扰了测试物体自己”的现象)。

咱们通常的作法是,先用抽样的方法找到效能瓶颈所在,而后对特定的模块用代码注入的方法进行详细分析。

对程序进行效能分析,咱们先要弄清下面这几个名词,如表9-1所示:

9-1  效能分析的名词解释

  

  

调用者Caller

函数Foo()中调用了Bar()Foo()就是调用者

被调用函数Callee

见上,Bar()就是被调用函数

调用关系树Call Tree

从程序的Main()函数开始,调用者和被调用函数就造成了一个树形关系—调用树

消逝时间Elapsed Time

从用户的角度来看程序运行所花的时间。当用户看到一个程序没有反应,用户并不知道程序此时是在运行本身的代码,仍是被调度出去了,或者操做系统此时正在忙别的事情

应用程序时间Application Time

应用程序占用CPU的时间,不包括CPU在核心态时花费的时间

 

续表

  

  

本函数时间Exclusive Time

全部在本函数花费的时间,不包括被调用者使用的时间

全部时间Inclusive Time

包含本函数和全部调用者使用的时间

理解了上面的各类概念后,咱们就不难理解“消逝的本函数时间(Elapsed Exclusive Time)”等其余组合名词所表明的概念了。

咱们先进行抽样分析,在效能浏览器(Performance Explorer)中开始效能分析便可。

9-2WordFreq程序处理一个30KB的文本文件时的状况:

clip_p_w_picpath004

9-2  用抽样的方法分析效能

你们能够看到最花时间的三个函数是:

WordFreq.Freq.FreqOneWord(string)

System.String.EqualsHelper(string,string)

System.Collections.ArrayList.get_Item(int32)

三个函数加起来占用了整个程序84%的时间。看来咱们得分析为何这三个函数会被调用得这么频繁,开销这么大了。

们如今能够进行代码注入的分析,一样运行程序后,咱们看看图9-3的调用树(Call Tree报告。

clip_p_w_picpath006

9-3  代码注入方法产生的效能报告

 

结合实际的代码(见代码清单9-4),能够看到在WordFreq. FreqOneWord函数中,究竟发生了什么:

代码清单9-4  FreqOneWord()

 private void FreqOneWord(string w)
        {
            // see if we have a match, if not, add it to the end,
            // then assign it initial frequency 1;
            // if yes, inc the frequency by 1
            for (int i = 0; i < m_wordList.Count; i++)
            {
                Frequency fi = (Frequency)m_wordList[i];
 
                if (fi.str == w)
                {
                    fi.n++;
                    return;
                }
            }
 
            //now we have to append it to the end.
            Frequency f = new Frequency();
            f.str = w;
            f.n = 1;
            m_wordList.Add(f);
        }
相关文章
相关标签/搜索