程式越來越大,為了讓程式更快地響應使用者的輸入,需要執行性能測試,最近在研究性能測試,就從這篇最基礎的文章開始起步吧。VS 2010自帶了一個功能強大的性能測試工具—Performance Wizard,在研究過程中,我決定用通過分析最普通的排序操作的程式來開始我的學習過程。
程式的功能很簡單,接受任何文本檔案,排序,然後将結果輸出到一個新的檔案中。第一個版本很簡單,使用最好寫的冒泡排序實作:
#region 常見的排序方法 — 适合小檔案的排序
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: sort <file name> <output file name>");
return;
}
string[] sortedLines;
using (StreamReader reader = new StreamReader(Path.GetFullPath(args[0])))
var text = reader.ReadToEnd();
sortedLines = Sort(text);
using (StreamWriter writer = new StreamWriter(Path.GetFullPath(args[1])))
foreach (var line in sortedLines)
writer.WriteLine(line);
}
#region 使用冒泡排序來測試性能
// V1: 使用冒泡排序來測試性能
private static string[] Sort(string text)
var lines = text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < lines.Length; ++i)
for (int j = i + 1; j < lines.Length; ++j)
{
if (string.CompareOrdinal(lines[i], lines[j]) < 0)
{
var temp = lines[i];
lines[i] = lines[j];
lines[j] = temp;
}
}
return lines;
#endregion
使用一個大小為2.5 兆的文本檔案作為輸入資料,并且用下面的步驟執行性能測試:
1. 打開Visual Studio,并點選菜單欄裡的“分析(Analyze)”。
2. 點選“啟動性能測試向導(Launch Performance Wizard)”。
3. 在“性能測試向導(Performance Wizard)”頁面上選擇“CPU Sampling (recommended)”。
4. 在後續頁面上,使用頁面預設的選項做完設定。
耐心等待程式執行完以後,Visual studio會提供一個報表,在摘要(Summary)裡面—下圖,可以看到,程式使用了大約36秒才完成了所有的過程。
另外,在Hot Path表格裡,也可以看出,String.CompareOrdinal函數所占用的時間是最多的,占整個程式執行的78.44%。而從另外一個統計表Functions,這個統計表顯示了在程式執行完畢之前,函數觸發樣例的次數,注意,這個樣例觸發的次數和函數被調用的次數沒有對應關系,兩個樣例之間,函數可能被調用了多次,而且多個函數也可能被調用到—這個跟我們使用“CPU Sampling (recommended)”的政策有關,它的優點是快不影響被測程式的運作,缺點就是不夠精确。從Functions的統計表裡面,可以看到String.CompareOrdinal被調用到的次數是其他函數的好幾倍:
既然已經知道冒泡排序是整個程式的瓶頸了,那我們第二個版本就是将冒泡算法改成快速排序,看看有沒有改進:
#region 常見的排序方法 — 适合小檔案的排序
}
#region 使用快速排序來測試性能
// V2: 使用快速排序來測試性能
QuickSort(lines, 0, lines.Length - 1);
private static int Partition(string[] lines, int lower, int upper)
var pivot = lines[upper];
var newPivot = lower - 1;
for (int i = lower; i < upper; ++i)
if (string.CompareOrdinal(pivot, lines[i]) > 0)
var temp = lines[i];
newPivot = newPivot + 1;
lines[i] = lines[newPivot];
lines[newPivot] = temp;
++newPivot;
lines[upper] = lines[newPivot];
lines[newPivot] = pivot;
return newPivot;
}
private static void QuickSort(string[] lines, int lower, int upper)
if (lower < upper)
var pivot = Partition(lines, lower, upper);
QuickSort(lines, lower, pivot - 1);
QuickSort(lines, pivot + 1, upper);
這次的結果要比上次好很多,這次隻用了3秒多就完成了所有的工作,而且在Hot Path裡面,String.CompareOrdinal函數在程式執行時間的比重也下降了很多。
雖然我們從總的執行時間上來看,看到了很大的性能提高,但是知道那些函數的執行效率提高了,會讓你更直覺的感覺到後續性能優化的目标。VS 2010支援對比多個性能報告,并給出兩個報告之間的差别,例如哪些函數的執行速度有提高之類的:
1. 點選菜單欄裡的“分析(Analyze)”。
2. 點選“Compare Performance Report”,在彈出來的對話框裡選擇兩個性能測試的報告。
上圖裡,我在“Column” 裡面選擇了“Exclusive Samples”—因為對比百分比對我來說不夠直覺。從對比的結果來看,快速排序在各個方面全面勝出—除了Partition函數,因為那是一個新函數。
接下來,為了檢視快排對大檔案排序的性能,我使用了一個700多兆的文本檔案進行測試,這次—程式崩潰了,崩潰的原因是OutOfMemoryException……
下一篇講解OutOfMemoryException的分析過程。
本文轉自 donjuan 部落格園部落格,原文連結: http://www.cnblogs.com/killmyday/archive/2010/06/20/1761583.html ,如需轉載請自行聯系原作者