날짜 시간입니다.기능의 성능을 측정하는 가장 좋은 방법은 무엇입니까?
병목 현상을 찾아 가능한 정확하게 시간을 측정해야 합니다.
다음 코드 스니펫이 성능을 측정하는 가장 좋은 방법입니까?
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);
스톱워치는 자동으로 고정밀 타이머의 존재를 확인합니다.
을 언급할 가치가 있습니다.DateTime.Now
종종 보다 꽤 느립니다.DateTime.UtcNow
시간대, DST 등으로 수행해야 하는 작업으로 인해.
날짜 시간.UtcNow의 해상도는 일반적으로 15ms입니다.John Chapman의 블로그 게시물 보기DateTime.Now
대요약을 위한 정확성.
흥미로운 사소한 것들:스톱워치가 다시 켜집니다.DateTime.UtcNow
하드웨어가 고주파 카운터를 지원하지 않는 경우.고정 필드 Stopwatch를 보면 Stopwatch가 하드웨어를 사용하여 고정밀을 달성하는지 확인할 수 있습니다.고해상도입니다.
빠르고 더러운 것을 원한다면 정밀도를 높이기 위해 스톱워치를 사용하는 것이 좋습니다.
Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();
Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);
또는 조금 더 정교한 것이 필요한 경우 ANTS와 같은 타사 프로파일러를 사용하는 것을 고려해야 합니다.
이 기사는 우선 세 가지 대안을 비교해야 한다고 말합니다.Stopwatch
,DateTime.Now
그리고.DateTime.UtcNow
.
또한 일부 경우(성능 카운터가 없는 경우)에는 StopWatch가 DateTime을 사용하고 있음을 보여줍니다.UtcNow + 약간의 추가 처리.그 때문에 이 경우 DateTime이 분명합니다.UtcNow가 가장 좋은 옵션입니다(다른 사용자가 사용 + 일부 처리).
그러나 밝혀진 바와 같이 카운터는 거의 항상 존재합니다. .NET Stopwatch와 관련된 고해상도 성능 카운터 및 그 존재에 대한 설명을 참조하십시오.
여기 성능 그래프가 있습니다.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);
}
스톱워치 기능이 더 낫습니다(높은 정밀도).인기 있는 프로파일러 중 하나만 다운로드하는 것이 좋습니다. (도트 트레이스와 ANTS는 제가 가장 많이 사용한 프로파일러입니다.)DotTrace의 무료 평가판은 완전히 작동하며 다른 일부 버전처럼 잔소리가 없습니다.
시스템을 사용합니다.진단.감시 수업을 중지합니다.
Stopwatch sw = new Stopwatch();
sw.Start();
// Do some code.
sw.Stop();
// sw.ElapsedMilliseconds = the time your "do some code" took.
스톱워치와 마찬가지로, 그것은 훨씬 더 좋습니다.
성능 측정과 관련하여 "// 일부 실행 프로세스"가 매우 짧은 프로세스인지 여부도 확인해야 합니다.
또한 "// 일부 실행 프로세스"의 첫 번째 실행이 이후 실행보다 훨씬 느릴 수 있습니다.
저는 일반적으로 루프에서 1000번 또는 1000000번 실행하는 방법을 테스트하며 한 번 실행하는 것보다 훨씬 정확한 데이터를 얻습니다.
이는 모두 시간을 측정하는 훌륭한 방법이지만 병목 현상을 찾는 매우 간접적인 방법일 뿐입니다.
스레드에서 병목 현상을 찾는 가장 직접적인 방법은 스레드를 실행하는 것이며, 대기하게 만드는 모든 작업을 수행하는 동안 일시 중지 또는 브레이크 키를 사용하여 중지합니다.이 작업을 여러 번 수행합니다.병목 현상에 X%의 시간이 소요되는 경우 X%는 각 스냅샷에서 병목 현상이 실제로 발생할 확률입니다.
작동 방식과 이유에 대한 자세한 설명은 다음과 같습니다.
@씨언 체임버스
참고로 .NET 타이머 클래스는 진단용이 아닙니다. 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);
}
그래서 이것은 어떤 것이 얼마나 오래 걸렸는지를 아는 데 도움이 되지 않습니다. 단지 일정한 시간이 지났다는 것입니다.
타이머는 시스템에서도 컨트롤로 노출됩니다.창문들.양식...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 대신 Stopwatch 사용을 참조하여 정확한 성능 카운터를 확인하십시오.
Visual Studio Team System에는 이 문제를 해결하는 데 도움이 될 수 있는 몇 가지 기능이 있습니다.기본적으로 스트레스 또는 부하 테스트의 일부로 소프트웨어에 대해 실행하기 위해 유닛 테스트를 작성하고 다양한 시나리오에서 혼합할 수 있습니다.이렇게 하면 응용 프로그램 성능에 가장 큰 영향을 미치는 코드 영역을 식별하는 데 도움이 될 수 있습니다.
Microsoft의 패턴 및 관행 그룹은 Visual Studio Team 시스템 성능 테스트 지침에 몇 가지 지침을 제공합니다.
밴스 모리슨의 블로그에서 그가 작성한 코드타이머 수업에 대한 게시물을 발견했습니다.StopWatch
더 쉽고, 옆에서 깔끔한 일을 합니다.
프로그램에서 사용하는 방법은 여기에 나와 있는 것처럼 StopWatch 클래스를 사용하는 것입니다.
Stopwatch sw = new Stopwatch();
sw.Start();
// Critical lines of code
long elapsedMs = sw.Elapsed.TotalMilliseconds;
저는 이런 종류의 성능 점검을 거의 해본 적이 없기 때문에 (저는 "이 작업이 더 느리고 더 빨리 진행될 것"이라고 생각하는 경향이 있습니다.) 그래서 저는 거의 항상 이것을 사용해 왔습니다.
Google은 성능 검사를 위해 많은 리소스/기사를 제공합니다.
많은 사람들이 성능 정보를 얻기 위해 핀보케를 사용한다고 언급합니다.제가 공부하는 많은 자료들은 perfmon을 사용하는 것에 대해서만 언급하고 있습니다.
편집:
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를 추가할 것입니다.관리 힙을 알려진 상태로 변경하기 위해 호출을 수집하고 ETW 프로필에서 다른 코드 간격을 쉽게 분리할 수 있도록 절전 호출을 추가합니다.
저는 정밀도에 대해 별로 신경 쓰지 않기 때문에 결국 그것들을 비교하게 되었습니다.네트워크에서 많은 패킷을 캡처하고 있으며 각 패킷을 수신하는 시간을 지정하고 싶습니다.여기 5백만 번의 반복을 테스트하는 코드가 있습니다.
int iterations = 5000000;
// Test using datetime.now
{
var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (date == DateTime.Now)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using datetime.now. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
// Test using datetime.utcnow
{
var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (date == DateTime.UtcNow)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using datetime.utcnow. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
// Test using stopwatch
{
Stopwatch sw = new Stopwatch();
sw.Start();
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (sw.ElapsedTicks == DateTime.Now.Ticks)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using stopwatch. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
출력은 다음과 같습니다.
Done executing 5000000 iterations using datetime.now. It took 0.8685502 seconds
Done executing 5000000 iterations using datetime.utcnow. It took 0.1074324 seconds
Done executing 5000000 iterations using stopwatch. It took 0.9625021 seconds
결론적으로 DateTime입니다.UtcNow는 정밀도에 대해 크게 신경 쓰지 않는 경우가 가장 빠릅니다.이것은 또한 이 질문의 답변 https://stackoverflow.com/a/6986472/637142 을 지원합니다.
언급URL : https://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance
'programing' 카테고리의 다른 글
변경된 입력 텍스트 상자 탐지 (0) | 2023.05.23 |
---|---|
Linux Bash에서 더블 앰퍼샌드(&&)와 세미콜론(;)의 차이점은 무엇입니까? (0) | 2023.05.23 |
엑셀 파일의 문자 인코딩을 확인하려면 어떻게 해야 합니까? (0) | 2023.05.23 |
iOS 7 반투명 UI 탐색 모음을 위한 밝고 선명한 색상 구현 (0) | 2023.05.23 |
SqlDataAdapter입니다.주입 방법이 느림 (0) | 2023.05.23 |