2013-11-04 7 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 

이 샘플은 한 번에 나온 문자열로 상당히 크게 시작되었지만 처음부터 패턴이 유지됩니다. 대개 처음 1,000 개 정도의 샘플은 패턴을 알아보기에는 너무 작지만 1.8k 마크 주변에서는 인식 할 수 있습니다.

내 첫 번째 가정은 배후에서 그 캐릭터가 일종의 ArrayList/vector 유형 거래에 저장되었다는 것입니다.이 거래는 일단 가득 찼 으면 크기가 두 배가되지만, 더 많이 생각하면 적합하지 않습니다. 그러한 경우 스파이크는 선형이 아닌 지수 기간에 나타납니다.

그래서 간단히 말해서 여기서 뭐하고있는거야?

+0

아마도 가비지 수집 일 것입니다. 정말로 관심이 있다면 프로파일 러를 실행 해보십시오. 추측 할 수는 없지만 – CodeCaster

+0

GC는 정확히 6 번째 반복마다 발생할만큼 일관성이 있습니까? (전체 데이터 세트에서 일관성이 있다고 가정 할 때)? – Polynomial

답변

3

문자열을 생성하고 삭제하면 가비지가 생성됩니다. 일정량의 메모리를 사용하면 가비지 콜렉션이 발생하고 프로세스가 일시 중지됩니다. 당신의 과정에서 다른 일이 일어나지 않고 항상 당신의 줄을 같은 길이로 만들 때, GC는 항상 같은 시간에 (6 회마다) 발생합니다.

타이밍에 미치는 영향을 방지하려면 각 실행시 타이머를 시작하기 전에 GC.Collect으로 전화하십시오.