2011-01-11 13 views
5

정말, Windows 운영 체제에서 주어진 C# 함수의 시간주기를 정확하게 측정하는 좋은 함수를 찾고 있습니다. 나는이 기능을 시도했지만 둘 다 정확한 측정을하지 않습니다 사람이 더 나은 방법을 알고있는 경우C# 함수의 시간주기를 측정하는 가장 좋은 방법은 무엇입니까?

DateTime StartTime = DateTime.Now;  
TimeSpan ts = DateTime.Now.Subtract(StartTime); 
Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
//code to be measured 
stopWatch.Stop(); 
TimeSpan ts = stopWatch.Elapsed; 

정말, 내가 그들을 호출 할 때마다, 그들은, 동일한 기능

제발 나에게 다른 시간을 제공 시간이 많이 걸리는 시간을 측정하십시오. 제발 도와 주셔서 감사합니다. 많이

답변

7

스톱워치는 기능을 실행하는 데 걸리는 시간을 측정하는 데 권장되는 방법입니다. 다양한 소프트웨어 및 하드웨어 요소로 인해 실행에서 실행까지 동일하지 않습니다. 이는 성능 분석이 일반적으로 많은 수의 실행에서 수행되고 시간이 평균화되는 이유입니다.

+0

답장을 보내 주셔서 감사합니다 ... 실행 횟수가 많은 평균 시간을 사용하는 대신 다른 프로세스의 영향을받지 않고 코드 프로세스의 클럭 사이클 만 측정하는 방법에 대해 들었습니까? – Duaa

4

"그들은 동일한 기능을하는 데 다른 시간을줍니다"- 예상대로입니다. 시스템에서 실행중인 유일한 프로세스가 아니기 때문에 상황이 변동합니다.

큰 루프에서 시간을 측정하려는 코드를 실행하여 변동을 평균합니다 (총 시간을 루프 수로 나눕니다).

Stopwatch은 정확한 타이머이며 대부분의 상황에 적절한 타이밍입니다.

const int numLoops = 1000000; // ...or whatever number is appropriate 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 

for (int i = 0; i < numLoops; i++) 
{ 
    // code to be timed... 
} 

stopWatch.Stop(); 
TimeSpan elapsedTotal = stopWatch.Elapsed; 
double timeMs = elapsedTotal.TotalMilliseconds/numLoops; 
+0

+1 그리고 저는 항상 측정 할 때 현재 프로세스/스레드 우선 순위를 가장 높게 설정했습니다. –

+0

답장을 보내 주셔서 감사합니다.하지만 내 코드가 길기 때문에 기다리는 시간이 너무 길어서 1000000 번에 걸쳐 코드를 반복 할 수 없다고 생각합니다. 시간이 너무 오래 걸릴 것입니다 ... 내 다른 프로세스의 영향을받지 않고 코드 프로세스? – Duaa

+0

루프의 크기를 1000 또는 10000으로 줄이십시오. –

1

골드 표준은 StopWatch입니다. 그것은 고해상도 타이머이며 매우 잘 작동합니다.

.Elapsed.TotalMilliSeconds을 사용하면 .Elapsed.MilliSeconds이 아닌 double이 표시되어 경과 시간을 확인하는 것이 좋습니다 (int이 제공됩니다). 결과가 나오지 않을 수 있습니다.

또한 가비지 수집이 타이밍 테스트 중에 발생하며 이로 인해 결과 시간이 크게 변경 될 수 있습니다. 타이밍 테스트의 전후에 GC 수집 횟수를 확인하고 가비지 콜렉션이 발생하면 결과를 무시하는 것이 유용합니다.

그렇지 않으면 다른 스레드와 프로세스가 테스트 중에 CPU 및 기타 시스템 리소스를 차지하기 때문에 결과가 다를 수 있습니다. 여러 번 테스트를 실행하고 평균 & 표준 편차 타이밍 등을 계산하여 통계적으로 결과를 분석하는 것 외에는 할 수있는 일이 많지 않습니다.

이 정보가 도움이되기를 바랍니다.

+0

답장을 보내 주셔서 감사합니다. 많은 횟수의 평균 시간을 사용하는 대신 내 시간의 클럭주기 만 측정하는 방법에 대해 들었습니까? 다른 프로세스의 영향을받지 않고 코드 프로세스? – Duaa

+0

@Duaa - AFAIK 운영 체제 프로세스가 필요하므로 코드가 처음 실행될 수 있도록 보장 할 방법이 없습니다. 당신이 그 (것)들을 그 후에 멈출 수 있던 경우에 당신의 부호는 또한 정지하고 당신은 어떤 타이밍도 할 수 없을 것입니다. 테스트에서 다른 프로세스와 스레드를 허용해야합니다. 이것이 통계를 사용해야하는 이유입니다. 답장을 보내 – Enigmativity

+0

덕분에 답장을 보내 – Duaa

1

클록 주기로 코드를 측정 할 수는 있지만 몇 초 만에 측정하는 것과 마찬가지로 변동성이 크며 훨씬 유용하지는 않습니다 (초는 더 좋지는 않더라도 좋기 때문에 클록주기보다 측정 단위). 다른 프로세스가 영향을받지 않는 측정을 얻는 유일한 방법은 아무 것도 실행하지 않는 것입니다. Windows에서는이 작업을 수행 할 수 없습니다. 단일 프로세스 OS가 아니기 때문에 OS 자체가 항상 일부 작업을 수행합니다. .

원하는 측정치에 가장 근접한 것은 코드 as described here을 만들고 실행하는 것입니다. 그런 다음 코드 시작 부분에 중단 점을 설정하고 단계별로 실행하여 시간을 측정하려는 메서드에 대한 JIT 코드의 x86 어셈블리를 볼 수 있습니다. 인텔 아키텍처 설명서에서 각 x86 명령어와 사이클 타이밍을 상호 참조하고 정확한주기 수를 더할 수 있습니다.

물론 이것은 매우 고통스럽고 기본적으로 쓸모가 없습니다. 또한 JIT가 IL에서 x86을 작성하는 데 약간 다른 접근 방식을 사용하게하는 코드 변경으로 인해 무효화 될 수도 있습니다.

+0

덕분에 답장을 보내 – Duaa

0

다른 사람을 에코하려면 : Stopwatch 클래스가이를 수행하는 가장 좋은 방법입니다.

클럭 사이클 측정에 대한 질문에 답하려면 : 최신 프로세서의 멀티 태스킹 OS에서 실행한다는 사실은 거의 쓸모없는 클럭 사이클을 측정합니다. 컨텍스트 스위치는 프로세서 캐시에서 코드와 데이터를 제거 할 수있는 좋은 기회를 제공하며, OS는 그 동안에 작업 세트를 교환하기로 결정할 수 있습니다.

프로세서는 캐시 대기 또는 메모리 액세스를 기반으로 지침의 순서를 변경하고 대기 중에 수행 할 수있는 작업을 결정할 수 있습니다. 또는 캐시에없는 경우가 있습니다.

그래서 간단히 말해서 여러 번 실행하고 평균하여 실행하는 것이 실제로 유일한 방법입니다.

시간에 따른 지터를 줄이려면 스레드/프로세스의 우선 순위를 높일 수 있지만 그럴 경우 다른 문제가 발생할 수 있습니다 (실시간 우선 순위에 부딪히면서 긴 루프에서 멈추는 것은 본질적으로 달라집니다). 다른 모든 처리를 중단하십시오. 버그가 발생하고 무한 루프에 빠지면 리셋 버튼 만 선택할 수 있습니다. 특히 사용자 컴퓨터 또는 프로덕션 환경에서는 권장되지 않습니다. 그리고 중요한 부분에서는 그렇게 할 수 없으므로 우선 순위를 수정하여 시스템에서 실행하는 벤치 마크를 무효로 만듭니다.

+0

덕분에 답장을 보내 – Duaa

1

코드 실행을 측정하려면 프로파일 러가 필요합니다 (검색을 시작하려면 What Are Some Good .NET Profilers? 참조).

귀하의 의견을 보면 귀하가 최적화하려고하는 것이 명확하지 않습니다. 일반적으로 코드가 실행될 때 CPU 클럭 사이클을 측정하기 위해 내려야하고, 다른 경우에는 함수 당 실행 시간이 보통 충분합니다. 하지만 코드가 너무 느려서 스톱워치로 평균 시간을 계산하지 못한다고 말하는 것입니다.

또한 CPU가 응용 프로그램의 병목 지점인지 또는 느려지는 것이 있는지 알아야합니다. TaskManager의 CPU %를 보면 100 % 미만의 CPU 사용량으로 정보를 얻을 수 있습니다. 다른 프로그램 (예 : 네트워크 또는 디스크 활동)이 프로그램을 느리게 만듭니다.

성능 목표를 달성하기 위해 측정하려는 코드 유형을 기본적으로 자세히 제공하면 훨씬 쉽게 도움을받을 수 있습니다.

+0

덕분에 ... 내가 그 시간을 측정하려고 노력하고있어 나는 C#으로 프로그램 수정 된 문자열 매칭 알고리즘 내가 그 성능을 비교하려면 다른 문자열 일치 알고리즘, 특히 시간 measurmenet에 대한, 내 수정 된 문자열 일치 알고리즘이 다른 것보다 빠르다는 것을 보장하기 위해 ... 대단히 감사합니다 – Duaa

0

을 사용하여 시작과 끝을 캡처 한 다음 TimeSpan.FromTicks()을 캡처하는 방법은 무엇입니까?

관련 문제