現代軟件工程講義 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);
        }
相關文章
相關標籤/搜索