메소드의 실행 시간 계산


533

가능한 중복 :
기능이 얼마나 오래 실행되는지 측정하는 방법은 무엇입니까?

위치에서 다른 위치로 데이터를 복사하는 I / O 시간 측정 방법이 있습니다. 실행 시간을 계산하는 가장 좋고 실제적인 방법은 무엇입니까? Thread? Timer? Stopwatch? 다른 해결책? 나는 가장 정확한 것을 원하고 최대한 짧게 원한다.

답변:


1130

Stopwatch 이 목적을 위해 설계되었으며 .NET에서 시간 실행을 측정하는 가장 좋은 방법 중 하나입니다.

var watch = System.Diagnostics.Stopwatch.StartNew();
// the code that you want to measure comes here
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;

.NET에서 시간 실행을 측정 하기 위해 DateTime 사용 하지 마십시오 .


최신 정보:

주석 섹션에서 @ series0ne이 지적한 것처럼 : 일부 코드 실행을 실제로 정확하게 측정하려면 운영 체제에 내장 된 성능 카운터를 사용해야합니다. 다음 대답은 멋진 개요가 포함되어 있습니다.


2
정확히, 그리고이 경우는 어떻습니까? ThreadPool.QueueUserWorkItem(delegate { CopyFiles(folder, dest); }); 내부에 foreach 루프가 있지만 모든 것이 완료되기 전에 스톱워치가 멈 춥니 다.
Mahdi Tahsildari

13
@DarinDimitrov-스톱워치는 완전히 정확하지 않습니까? .NET 백그라운드 노이즈 (예 : JITing)로 인해 다양한 실행 시간이 발생합니다. 따라서 현실적으로 정확한 측정을 위해 OP는 성능 프로파일 러를 사용해야합니다.
Matthew Layton

3
@ series0ne, 아주 좋은 지적. 소중한 의견을 포함하도록 답변을 업데이트하겠습니다.
Darin Dimitrov

7
@DarinDimitrov, 나는 최근에 매우 숙련 된 선임 개발자와의 인터뷰를 가졌습니다. 그는 DateTimes를 사용하는 것이 실제로 StopWatch를 사용하는 것보다 더 정확하다고 지적했습니다. 그는 .NET의 Stopwatch가 CPU 선호도를 고려하지 않기 때문에 스레드가 한 코어에서 다른 코어로 이동하면 StopWatch는 다른 코어의 실행 시간을 고려하지 않기 때문입니다. 스레드가 실행을 시작한 곳만 이것에 대한 당신의 의견은 무엇입니까?
Matthew Layton

2
@ series0ne, 선임 개발자가 스톱워치 및 DateTime에 대해 말한 내용은 사실입니다. DateTime을 사용하면 정확도가 충분하지 않습니다. 문제는 .NET에는 이러한 기능을 모두 허용하는 클래스가 없다는 것입니다.
Darin Dimitrov

75

개인적인 경험을 통해이System.Diagnostics.Stopwatch 클래스를 사용하여 메소드의 실행 시간을 측정 할 수 있지만 주의 해야합니다. 완전히 정확하지는 않습니다.

다음 예제를 고려하십시오.

Stopwatch sw;

for(int index = 0; index < 10; index++)
{
    sw = Stopwatch.StartNew();
    DoSomething();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

sw.Stop();

결과 예

132ms
4ms
3ms
3ms
2ms
3ms
34ms
2ms
1ms
1ms

이제 궁금합니다. "왜 처음에는 132ms가 걸렸고 나머지 시간은 크게 줄었습니까?"

정답은 StopwatchJITing과 같은 .NET의 "배경 소음"활동을 보상하지 않습니다. 따라서 처음으로 메소드를 실행할 때 .NET JIT가 먼저입니다. 이를 수행하는 데 걸리는 시간이 실행 ​​시간에 추가됩니다. 마찬가지로 다른 요인들도 실행 시간을 변화시킵니다.

절대 정확도를 찾아야 할 것은 성능 프로파일 링입니다 !

다음을 살펴보십시오.

RedGate ANTS Performance Profiler는 상용 제품이지만 매우 정확한 결과를 생성합니다. - .NET 프로파일 링과 응용 프로그램의 성능을 향상

프로파일 링에 대한 StackOverflow 기사는 다음과 같습니다.- 좋은 .NET 프로파일 러 란 무엇입니까?

또한 스톱워치를 사용하여 성능 프로파일 링에 대한 기사를 작성 했습니다. .NET의 성능 프로파일 링


2
@mahditahsildari 문제 없습니다. 기꺼이 도와 드리겠습니다! :-)
Matthew Layton

41
왜 이것이 부정확 의 예인지 잘 모르겠습니다 . 스톱워치는 첫 번째 통화의 총 비용을 정확하게 측정하고 있으며, 이는이 코드를 실행할 고객과 관련이 있습니다. 132 밀리 초가 메소드 실행 또는 지터에 부과되는지 여부는 상관하지 않으며 총 경과 시간을 고려합니다.
Eric Lippert

2
@ series0ne 루프의 성능에 관심이 있다면 루프의 성능을 측정하십시오. 단순히 n 번 무언가 를하는 것이 한 번만 실행하는 것보다 정확히 n 배 느리다 는 것을 가정하지 마십시오 .
svick

3
우선 코드 샘플은 루프에서 StopWatch가 재설정되지 않으므로 점점 증가하는 숫자로 출력을 생성해야합니다. 그리고 "해야한다"라는 말이 있습니다. 따라서 출력이 코드와 일치하지 않습니다. 둘째, 루프에서 Stop / Write / Reset / Start를 수행하도록 코드를 수정했을 때 첫 번째 측정은 나머지 측정과 동일했습니다. 내 생각에 당신의 DoSomething은 처음 실행될 때 더 오랫동안 무언가를합니다. JIT가 그 이유 일 수도 있고 아닐 수도 있지만, 스톱워치가 측정에 영향을 미치는 것은 아닙니다. 따라서 -1.
ILIA BROUDNO

2
ILIA BROUDNO는 절대적으로 정확합니다. 동일한 결과를 얻었습니다. @ series0ne, 루프 안에 Console.WriteLine이 있으며 지금까지 ms를 작성합니다. 루프가 끝난 후에 만 ​​시계를 중지하기 때문에 각 반복마다 시간이 지남에 따라 시계가 증가하므로 실행 시간이 지남에 따라 3, 6, 10, 12, 15와 같은 것을 볼 수 있습니다.
Rui Miguel Pinheiro

29

StopWatch 수업은 최고의 솔루션을 찾습니다.

Stopwatch sw = Stopwatch.StartNew();
DoSomeWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

또한라는 정적 필드가 Stopwatch.IsHighResolution있습니다. 물론 이것은 하드웨어 및 운영 체제 문제입니다.

타이머가 고해상도 성능 카운터를 기반으로하는지 여부를 나타냅니다.


18

성능 이해에 관심이있는 경우 가장 좋은 대답은 프로파일 러를 사용하는 것입니다.

그렇지 않으면 System.Diagnostics.StopWatch 는 고해상도 타이머를 제공합니다.


절대적으로 맞습니다! 나는 스톱워치 사용이 완전히 정확하지 않기 때문에 많은 사람들이 스톱워치 사용을 제안한 것에 대해 약간 실망했습니다. 그러나 성능 프로파일 러 사용을 제안한 올바른 방법입니다. +1
Matthew Layton

7

스톱워치 는 고해상도 카운터를 사용합니다

스톱워치는 기본 타이머 메커니즘에서 타이머 틱을 계산하여 경과 시간을 측정합니다. 설치된 하드웨어 및 운영 체제가 고해상도 성능 카운터를 지원하는 경우 Stopwatch 클래스는 해당 카운터를 사용하여 경과 시간을 측정합니다. 그렇지 않으면 Stopwatch 클래스는 시스템 타이머를 사용하여 경과 시간을 측정합니다. 빈도 및 IsHighResolution 필드를 사용하여 스톱워치 타이밍 구현의 정밀도 및 해상도를 판별하십시오.

IO를 측정하는 경우 수치가 외부 이벤트의 영향을받을 가능성이 높으므로 다시 걱정할 것입니다. 정확성 (위에 표시 한대로). 대신 다양한 측정을 수행하고 해당 수치의 평균과 분포를 고려했습니다.


0
 using System.Diagnostics;
 class Program
 {
    static void Test1()
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine("Test1 " + i);
        }
    }
  static void Main(string[] args)
    {

        Stopwatch sw = new Stopwatch();
        sw.Start();
        Test1();
        sw.Stop();
        Console.WriteLine("Time Taken-->{0}",sw.ElapsedMilliseconds);
   }
 }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.