병목 현상을 찾아야하며 가능한 측정 시간을 정확하게 측정해야합니다.
다음 코드 스 니펫이 성능을 측정하는 가장 좋은 방법입니까?
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
병목 현상을 찾아야하며 가능한 측정 시간을 정확하게 측정해야합니다.
다음 코드 스 니펫이 성능을 측정하는 가장 좋은 방법입니까?
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
답변:
아뇨. 스톱워치 사용 (에서 System.Diagnostics
)
Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);
스톱워치는 고정밀 타이머가 있는지 자동으로 확인합니다.
시간대, DST 등 으로 수행 해야하는 작업으로 인해 DateTime.Now
종종 속도가 약간 느리다는 것을 언급 할 가치가 DateTime.UtcNow
있습니다 .
DateTime.UtcNow의 해상도는 일반적으로 15ms입니다. 자세한 내용 은 정밀도에 대한 John Chapman의 블로그 게시물을 참조하십시오 DateTime.Now
.
재미있는 퀴즈 : DateTime.UtcNow
하드웨어가 고주파수 카운터를 지원하지 않으면 스톱워치가 다시 사용됩니다 . 정적 필드 Stopwatch.IsHighResolution 을 보면 Stopwatch가 하드웨어를 사용하여 고정밀도를 달성하는지 확인할 수 있습니다 .
PerformWork()
매우 짧은 경우 반복해서 전화를 걸고 통화 일괄 처리의 평균을 계산할 수있는 권장 사항을 추가해야 합니다. 또한 Stopwatch
타이밍 측정을 방해하는 스트로브 효과를 피하기 위해 전화를 시작 / 중지하지 않고 전체 통화 시간을 측정하십시오.
이 기사에서는 우선 세 가지 대안 Stopwatch
, DateTime.Now
AND 를 비교해야한다고 말합니다 DateTime.UtcNow
.
또한 스톱워치가 DateTime.UtcNow + 일부 추가 처리를 사용하는 경우도 있습니다 (성능 카운터가 존재하지 않는 경우). 이 경우 DateTime.UtcNow가 가장 좋은 옵션이라는 것이 분명합니다 (다른 사용 + 일부 처리 때문에)
그러나 결과적으로 카운터는 거의 항상 존재합니다. 고해상도 성능 카운터 및 .NET 스톱워치와 관련된 존재에 대한 설명은 무엇입니까? .
성능 그래프는 다음과 같습니다. 저비용 성능 UtcNow가 다른 제품과 비교 한 결과를 확인하십시오.
X 축은 샘플 데이터 크기이고 Y 축은 예제의 상대 시간입니다.
Stopwatch
더 좋은 점 은 더 높은 분해능 시간 측정을 제공한다는 것입니다. 다른 하나는 더 많은 OO 특성입니다. 그러나 OO 래퍼를 만드는 UtcNow
것은 어렵지 않습니다.
벤치마킹 코드를 유틸리티 클래스 / 방법으로 푸시하는 것이 유용합니다. StopWatch
클래스 일 필요는 없습니다Disposed
또는 Stopped
오류에. 그래서, 간단한 코드에 시간이 몇 가지 조치가 있다
public partial class With
{
public static long Benchmark(Action action)
{
var stopwatch = Stopwatch.StartNew();
action();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
}
샘플 호출 코드
public void Execute(Action action)
{
var time = With.Benchmark(action);
log.DebugFormat(“Did action in {0} ms.”, time);
}
확장 방법 버전은 다음과 같습니다.
public static class Extensions
{
public static long Benchmark(this Action action)
{
return With.Benchmark(action);
}
}
그리고 샘플 호출 코드
public void Execute(Action action)
{
var time = action.Benchmark()
log.DebugFormat(“Did action in {0} ms.”, time);
}
Elapsed.TotalMilliseconds
더 높은 정밀도를 위해 반환 합니다. 이 질문도 함께보십시오 stackoverflow.com/questions/8894425/…
이것들은 모두 시간을 측정하는 좋은 방법이지만 병목 현상을 찾는 매우 간접적 인 방법입니다.
스레드에서 병목 현상을 찾는 가장 직접적인 방법은 스레드를 실행하는 것입니다. 대기하는 작업을 수행하는 동안 일시 중지 또는 중지 키로 중지하십시오. 이 작업을 여러 번 수행하십시오. 병목 현상이 X %의 시간이 걸리면 X %는 각 스냅 샷의 동작에서이를 포착 할 확률입니다.
@ 션 챔버스
참고로 .NET Timer 클래스는 진단용이 아니며 다음과 같이 미리 설정된 간격으로 이벤트를 생성합니다 ( MSDN에서 ).
System.Timers.Timer aTimer;
public static void Main()
{
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
따라서 이것은 시간이 오래 걸린다는 것을 아는 데 실제로 도움이되지 않습니다.
타이머는 System.Windows.Forms의 컨트롤로도 노출됩니다 ... VS05 / VS08의 디자이너 도구 상자에서 찾을 수 있습니다
이것은 올바른 방법입니다.
using System;
using System.Diagnostics;
class Program
{
public static void Main()
{
Stopwatch stopWatch = Stopwatch.StartNew();
// some other code
stopWatch.Stop();
// this not correct to get full timer resolution
Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);
// Correct way to get accurate high precision timing
Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
}
}
자세한 내용은 정확한 성능 카운터를 얻기 위해 DataTime 대신 스톱워치 를 사용하십시오 .
Visual Studio Team System 에는이 문제를 해결하는 데 도움이되는 몇 가지 기능이 있습니다. 기본적으로 단위 테스트를 작성하고 다른 시나리오에서 혼합하여 스트레스 또는로드 테스트의 일부로 소프트웨어에 대해 실행할 수 있습니다. 이는 애플리케이션 성능에 가장 큰 영향을 미치는 코드 영역을 식별하는 데 도움이 될 수 있습니다.
Microsoft의 Patterns and Practices 그룹에는 Visual Studio Team 시스템 성능 테스트 지침에 대한 지침이 있습니다.
방금 Vance Morrison의 블로그에서 사용 하기 쉽고 측면에서 깔끔한 작업을 수행 하는 CodeTimer 클래스 에 대한 게시물을 찾았습니다 StopWatch
.
이것은 충분히 전문적이지 않습니다.
Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);
보다 안정적인 버전은 다음과 같습니다.
PerformWork();
int repeat = 1000;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
PerformWork();
}
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds / repeat);
실제 코드에서는 관리 힙을 알려진 상태로 변경하기 위해 GC.Collect 호출을 추가하고 ETW 프로파일에서 다른 코드 간격을 쉽게 분리 할 수 있도록 절전 호출을 추가합니다.
나는 이런 종류의 성능 검사를 거의하지 않았습니다 ( "이것은 느리고 빨리 만듭니다"라고 생각하는 경향이 있으므로).
구글은 성능 점검을위한 많은 리소스 / 기사를 공개합니다.
성능 정보를 얻기 위해 pinvoke를 사용하는 많은 사람들이 언급했습니다. 내가 공부하는 많은 자료는 perfmon을 사용해서 만 언급합니다.
스톱워치의 대화를 보았습니다. 나는 무언가를 배웠다 :)