2013-11-04 43 views
5

因此,出於好奇和無聊的無聊,我與基準Shlemiel the painter's algorithm鬼混。我從一個空白字符串開始,創建了1000個空格中的另一個空格,並開始向另一個添加一個,使用普通的低效字符串連接,每次計時需要多長時間。字符串串聯時,這種尖峯是什麼造成的?

string s1 = ""; 
string s2 = ""; 
while (s2.Length < 1000) 
{ 
    s2 += " "; 
} 

while (true) 
{ 
    Stopwatch sw = Stopwatch.StartNew(); 
    s1 += s2; 
    sw.Stop(); 

    Console.WriteLine(" {0}| {1}", s1.Length, sw.ElapsedMilliseconds); 
} 

正如預期的那樣,時間越長串了,花了來連接(這是比我預想的影響要小得多,但那是另一天另一個問題)的時間越長。然而,令人驚訝的是,所花費的時間是一致的尖峯。每六次連接花費的時間大約是前五次連接的兩到三倍。

Length  | Time (ms) 
----------------------- 
32250000 | 117 
32251000 | 44 
32252000 | 31 
32253000 | 30 
32254000 | 30 
32255000 | 32 
32256000 | 129 
32257000 | 35 
32258000 | 43 
32259000 | 34 
32260000 | 30 
32261000 | 29 
32262000 | 107 
32263000 | 47 
32264000 | 29 
32265000 | 30 
32266000 | 31 
32267000 | 29 
32268000 | 110 
32269000 | 46 
32270000 | 31 
32271000 | 30 
32272000 | 30 
32273000 | 30 
32274000 | 113 

這些樣本是從一旦字符串開始變得非常大,但模式從一開始就成立。大體上,前1000個樣本太小,無法注意到這種模式,但在大約1.8k處它是可識別的。

我的第一個假設是,在幕後,角色被存儲在某種類型的ArrayList/vector類型的deal中,一旦它滿了,它的大小加倍,但是當我考慮更多時,這不適合 - 如果是這樣的話,峯值會出現在指數週期,而不是線性。

所以,簡而言之:這到底是怎麼回事?

+0

可能是垃圾收集。如果你真的感興趣,可以嘗試運行一個profiler。恐怕我們只能猜測。 – CodeCaster

+0

GC是否足夠一致地發生正好每六次迭代(假設它對整個數據集一致)? – Polynomial

回答

3

創建字符串並放棄它們會產生垃圾。一旦你使用了一定數量的內存,就會發生垃圾回收並暫停你的進程。由於在你的過程中沒有其他任何事情發生,你總是讓你的字符串長度相同,GC總是在同一時間發生(每6次運行)。

爲避免對您的時間造成這種影響,請在每次運行啓動計時器之前致電GC.Collect

相關問題