2013-11-04 3 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); 
} 

予想したように、長い文字列が得た、もはやそれは(私が予想よりもはるかに小さい影響だったが、それは別の日の別の問題だ)連結しました。しかし、でしたが、驚くべきことに、時間がかかった時に一貫したスパイクでした。 6回目の連結では、前の5回連結の約2〜3倍の時間がかかりました。

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 /ベクタータイプの取引に格納されていたということでした。一度いっぱいになるとサイズが倍になりましたが、そうであれば、スパイクは線形ではなく指数関数的な期間に来るでしょう。

だから、要するにここで何が起こっているのですか?

+0

おそらくガベージコレクション。本当に興味がある場合はプロファイラを実行してみてください。私たちは推測することはできません。 – CodeCaster

+0

GCは完全に6回目の繰り返しで正確に発生します(データセット全体で一貫していると仮定します)。 – Polynomial

答えて

3

文字列を作成して破棄すると、ゴミが生成されます。一定量のメモリを使用すると、ガベージコレクションが発生し、プロセスが一時停止します。あなたのプロセスでは何も起こっておらず、あなたは常にあなたの弦を同じ長さにします.GCはいつも同じ時間に(6回目の実行ごとに)起こります。

タイミングに影響を与えないようにするには、実行ごとにタイマーを開始する前にGC.Collectに電話してください。

関連する問題