性能測試-函數性能分析篇
-Quantify
在利用ACT(Application Center Test)進行壓力測試後,如何對發現性能問題的模塊進行定位,發現性能瓶頸所在,這就需要大家瞭解一個性能分析工具,Rational Test Suite中的Quantify。Quantify是一款面向VB,VC,JAVA的函數級性能分析工具,它可以自動的檢測出影響程序運行的性能瓶頸,同時提供圖形化的分析表格,幫助程序員進行性能的分析與優化。
在性能優化的過程中,一些程序員往往是憑着經驗去分析自己所寫的代碼,找到性能瓶頸,這樣會面臨兩個問題:
1、 程序員所找到的性能瓶頸的代碼很可能是自己認爲不合理的算法,但在優化的過程中大家都知道性能的優化往往不是優化算法不合理的,而是主要優化佔用時間最長的函數;
2、 在一個大型的項目中,如何在成千上萬的代碼中找到性能瓶頸是一個最頭痛的問題,如果自己不瞭解所在的項目那就更無法下手;
那麼如何高效的提位問題,而不是通過代碼的檢查發現問題則是關鍵,而Quantify則是一款這樣的神兵利器。
Quantify有以下幾個特色:
1、 對當前的開發影響特別的少,還集成在一些通用的開發工具中,大大的增強了使用的容易度,比如Visual Studio;
2、 性能的顯示以圖形的方式進行,可以很直接的瞭解到性能所在的瓶頸;
3、 無需源代碼就可以對大多數的系統進行性能的分析;
4、 同時顯示的函數的信息非常的詳細,包含了調用的次數,時間等,還有相關的調用關係;
5、 在測試功能的同時,對性能進行分析,不需要額外的輔助代碼;
下面則是通過一個例子來詳細的介紹如何使用Quantify進行性能分析並發現問題,這裏我用CPPUnit寫了一個測試用例,用來測試一段性能有問題的代碼(代碼就不發出來了,呵呵),主要通過它讓大家瞭解Quantify是一個很簡單的工具:
l 對性能的測試只需要運行編譯好的程序,如圖:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
如圖1
l 生成的結果如下圖2,特別的簡單:
如圖2
不過要快速的分析,主要有以下幾點,首先給大家介紹幾個知識,算是瞭解一下,如果需要詳細的瞭解,這些是遠遠不夠的:
1. Function Time :函數本身執行的時間,它不包含子函數的時間;
2. F+D Time(Function+Descendants):函數本身與函數調用的子函數執行的時間;
3. Calls:函數在執行過程中調用的次數;
4. F Time(%):是函數本身(不包含子函數)佔用整個系統運行時間的百分比;
5. F+D Time(%):是函數本身消耗時間加子函數時間佔整個調用時間的百分比;
6. Avg F(Time):主要指函數平均運行時間;
7. Min F(Time):函數調用過程中最小的運行時間;
8. Max F(Time):函數調用過程中最大的運行時間;
9. Module:是那個DLL調用的;
在性能分析過程中,有一個原則就是優化佔用時間最長的函數或是佔百分比最長的函數,所以一般我會先關注Function Time與F Time(%),對此進行排序,從而發現性能上的問題,當然要與自己的系統相關的模塊,如圖:
如圖3
這裏你們可以看到與自己系統相關的是系統的輸出函數,它的calls次數非常的高,同時佔用時間與百分比也非常的多,呵呵,這時你就可以知道這是與系統相關的性能瓶頸,我的代碼中也是這樣寫的,呵呵。
//演示性能測試
void CMabString::DemoPer()
{
cout<<"Begin Performance/n";
int Result =0;
for (int j=0;j<1000;j++)
{
cout<<"This is Performance Test/n";
}
cout<<"End Performance/n";
}
當然你還可以通過圖形來發現你的函數由那些子函數組成,如圖:
如圖4
從這裏你可以看到CmabString::DemoPer下面調用的子函數是osteam,調用的次數是1002,佔性能的99.80%;同時還可以看到上一級函數,也就是調用CmabString::DemoPer的函數MathTest::testDemPer,通過圖形可以看到函數之間的調用關係,同時可以通過關聯深入跟蹤它的調用關係與性能情況,還是特別的方便的,不過要注意的是,有可能子函數調用的次數與佔用的性能甚至可以超過上一級函數,爲什麼,主要是這裏顯示了整個過程的調用次數,也就是說可能在其它地方也調用了此調用了此函數,所以這是一個很正常的現象。不過如果對系統不熟或是對工具不熟也會點的暈頭轉向,我已經暈了不知多少次了,哈哈。上面的例子則是很簡單的,就是循環佔用了時間。
上面的分析只是定位到函數,但是否可以定位到源碼級嗎?答案是肯定的。只要有源代碼,則可以從源碼級進行分析,你可以清楚的看到每一段代碼的執行時間,與函數執行時間,通過這種方法你可以更快的定位問題,如下圖:
圖5
這裏LineTime就是這行本身執行時間,Line+D是行執行時間與子樹執行的時間,通過源碼級的分析可以看到這段代碼的性能瓶頸就在for循環內,當然不一定可以優化,但如果可以優化則會提升的最明顯。
但性能問題不僅僅是代碼[寫的不好,還有一些是數據庫的問題或是網絡傳輸等等問題,當你發現如果是調用數據庫方法出問題或是網絡庫出問題時,可以轉入對網絡庫或是數據庫的分析。
Quantify還有其它很方便的地方,比如分析結果的保存很方便,支持多種語言,當然工具不是萬能的,最主要的是人的因素,希望能夠通過工具提高你的性能分析能力。