2014-03-12 301 views
7

在複雜的圖像處理算法的最後,我們有以下代碼將結果保存到文本文件。該函數的輸入是一個float[,] p_RangeMap表示圖像處理的輸出:.net性能週期?

StringBuilder stringBuilder = new StringBuilder(30 * 1024 * 1024); 
stringBuilder.AppendLine("Row" + ms_csvSeparator + p_RangeMap.GetLength(0)); 
stringBuilder.AppendLine("Col" + ms_csvSeparator + p_RangeMap.GetLength(1)); 

Stopwatch stopwatch = Stopwatch.StartNew(); 

for (int y = 0; y < p_RangeMap.GetLength(0); y++) 
{ 
    for (int x = 0; x < p_RangeMap.GetLength(1); x++) 
    { 
      stringBuilder.Append(p_RangeMap[y, x].ToString(CultureInfo.InvariantCulture)); 
      stringBuilder.Append(ms_csvSeparator); 
    } 
    stringBuilder.AppendLine(); 
} 

stopwatch.Stop(); 
Console.WriteLine("MeasureRunTime: RangemapConvert: " + stopwatch.Elapsed); 

通過測量這些線6000次的迭代的運行時,我們得到了如下圖:

Code running time

6000迭代大約需要24小時才能運行。水平軸表示迭代,垂直軸表示這些線以秒計算的運行時間。輸入對於每次迭代完全相同,並且p_RangeMap的尺寸是1312 x 3500.

它從大約兩秒開始,並且在上升到13秒之後,在900次迭代之後回落,並且(大約)900個週期形成一個週期。正如你所看到的最高值約爲22秒。

任何想法可能導致這種運行時變化?

什麼可能導致週期性?

可能值得一提的是,代碼的其他部分顯示了相同的行爲,但是這部分是從源代碼中最容易獲取的。

UPDATE1

我已經更新了代碼示例中,StringBuilder的是預分配與文件大小的一個粗略的估計。我們也考慮過垃圾回收,請考慮以下事項:

900個週期意味着大約3.5小時,大約16 GB的處理後的輸入數據(從文件一次又一次地加載相同的圖片)。更不用說因爲各種原因在圖像處理過程中創建的副本。我認爲GC應該更頻繁地觸發。

16 GB來源於:1312 * 3500 * 4 * 900

+10

考慮到操作涉及分配,我希望垃圾收集... –

+1

考慮預先分配的StringBuilder - 我認爲結果是相當大的,如果它有它的效率不高經常擴大規模。如果結果進入一個文件,請考慮在一個較小的stringbuilder中逐行輸出它 - 這看起來像gc問題,這是一個可能的原因。 – TomTom

+0

我已經更新了這個問題,StringBuilder是預先分配的。逐行輸出這些線條聽起來很有意思,我們可以嘗試。將更新與結果的職位。 – toderik

回答

1

首先看看:

我的猜測是內存問題。圖中的急劇下降看起來像是垃圾收集中的GC踢。

Stringbuilder相當高效,但我懷疑它是否在構建時考慮到這種情況。

5

這非常有趣。根據你的更新,你在哪裏分配16GB,你可能會考慮將你的Float數組和字符串生成器封裝在一個允許你重用緩衝區的類中,而不是在每次重新運行時重新分配它們。 (比如每次調用整個函數時重用相同的字符串構建器和數組,因此每6,000次運行只創建一個實例)

原因如下:您的構建器大小約爲30MB,因此它被分配到大對象堆中。 (任何時候分配超過85,000字節,它進入LOH)。關於LOH的GC規則有點不同。首先,它只是在第二代集合(最昂貴的類型)上GC'd,因此如果您大量創建並拆除大量分配,則可能會迫使Gen2集合更頻繁地發生。此外,LOH在第二代GC上沒有進行碎片整理(因爲它太昂貴了),所以當您分配大量數據時,您更可能導致GC,因爲您需要線性32MB。

如果你包裝你的浮點數組和字符串生成器,在你的字符串生成器之間調用Clear()來清空它而不釋放它,並且跟蹤float數組的已用大小。

這裏的一對LOH的文章:http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

+1

感謝您的鏈接,我們將盡力嘗試您的建議,並會通知您有關結果。 – toderik

+1

酷!期待它! – JMarsch

+1

您可以選擇壓縮.NET 4.5.1上的LOH - http://msdn.microsoft.com/en-us/library/system.runtime.gclargeobjectheapcompactionmode(v=vs.110).aspx –