2010-04-05 4 views
5

저는 C#을 처음 사용합니다. 나는 비교 목적으로 알고리즘을 취한 시간을 계산하려고 시도하고 있습니다. 다음 코드는 서브 루틴이 호출 될 때부터 서브 루틴이 주 프로그램으로 돌아갈 때까지의 경과 시간을 측정합니다.이 예제는 Michael McMillan의 "C#을 통한 데이터 구조"에서 가져온 것입니다. 이 프로그램을 실행하면 출력이 Time = 0으로 잘못되었습니다. 프로그램이 논리적으로 올바른 것 같습니다. 아무도 나를 도울 수 있습니까? 다음은 주요 기능에 어디서나 Timing 클래스를 사용하지 않고 당신도 시간을 인쇄 어디 보이지 않는 코드프로세스가 완료되는 데 필요한 시간이

using System; 
using System.Diagnostics; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Chap1 
{ 
    class chap1 
    { 
     static void Main() 
     { 
      int[] nums = new int[100000]; 
      BuildArray(nums); 
      Timing tObj = new Timing(); 
      tObj.startTime(); 
      DisplayNums(nums); 
      tObj.stopTime(); 
      Console.WriteLine("Time: " + tObj.result().TotalSeconds); 
      Console.WriteLine("Start Time: " + tObj.startTime().TotalSeconds); 
      Console.WriteLine("Duration : " + tObj.result().TotalSeconds); 
      Console.ReadKey(); 
     } 
     static void BuildArray(int[] arr) 
     { 
      for (int i = 0; i <= 99999; i++) 
       arr[i] = i; 
     } 
     static void DisplayNums(int[] arr) 
     { 
      for (int i = 0; i <= arr.GetUpperBound(0); i++) 
       Console.WriteLine(arr[i]); 
     } 
    } 
class Timing 
    { 
     TimeSpan StartTiming; 
     TimeSpan duration; 
     public Timing() 
     { 
      StartTiming = new TimeSpan(0); 
      duration = new TimeSpan(0); 
     } 
     public TimeSpan startTime() 
     { 
      GC.Collect(); 


    GC.WaitForPendingFinalizers(); 
      StartTiming = Process.GetCurrentProcess().Threads[0].UserProcessorTime; 
      return StartTiming; 
     } 
     public void stopTime() 
     { 
      duration = Process.GetCurrentProcess().Threads[0].UserProcessorTime.Subtract(StartTiming); 

     } 
     public TimeSpan result() 
     { 
      return duration; 
     } 
    } 
} 
+0

일부 온라인 리소스에 따라 디버그 모드로 실행하지 마십시오. – Kiril

+0

나는 똑같은 문제가 있었다! 벤 보이트 (Ben Voigt)는 맞습니다. 인덱스 0 (INDEX, Thread ID !!!)이있는 스레드가 관심있는 스레드라고 가정 할 수 없습니다. 이제 올바른 스레드 ID를 얻기 위해 PInvoke를 사용하여 GetCurrentThreadId . 그런 다음 모든 스레드를 반복하고 그 스레드 ID가있는 스레드를 확인합니다. – Jane

답변

3

Stopwatch class은이를 위해 설계되었습니다.

UserProcessorTime은 for 루프에서 100000까지 카운트를 측정하는 데 필요한 해상도를 갖기 시작하지 않습니다. 사용자의 WriteLine 호출은 I/O 시간이므로 사용자 시간에는 포함되지 않습니다. 코드는 스레드 0에서 실행되지 않을 수 있습니다. 컨텍스트 전환을 제외하고는 사용자 시간이 업데이트되지 않습니다. startTime을 인쇄하면 저장된 값이 변경됩니다. 아마도 내가 잘못 생각한 다른 것들이있을 수 있습니다.

CPU의 성능 카운터를 이용하는 Stopwatch 클래스를 사용하는 것이 좋습니다.

+0

@Ben OP가 왜이 예제가 작동하지 않는지 물어 본다. – Kiril

+0

친애하는 벤, 내가 지금 편집 한 올바른 코드를 참조 할 수 있다면 사과 드릴 것입니다. 감사합니다 –

+0

. NET 환경에서 모든 프로그램은 응용 프로그램 도메인 내에서 실행됩니다. 이를 통해 운영 체제는 동시에 실행중인 다른 프로그램을 분리 할 수 ​​있습니다. 프로세스 내에서 프로그램 또는 프로그램의 일부가 스레드 내에서 실행됩니다. 프로그램 실행 시간은 스레드를 통해 운영 체제에 의해 할당됩니다.프로그램의 코드를 타이밍 할 때 우리는 프로그램에 할당 된 프로세스 내에서 코드의 타이밍을 정확히 맞추고 운영 체제에서 수행하는 다른 작업은 수행하지 않도록해야합니다. 스톱워치 클래스를 사용하면 총 시간에서 다른 시간을 포함하게됩니다. –

2

입니다. 이 코드가 실행중인 코드입니까? 새로운 코드 당

업데이트 :

은 ... 디버그 모드에서 실행 귀하의 릴리스 버전을 구축하고 수동으로 실행 파일을 실행하지 마십시오 : 나는 당신의 코드를 테스트 http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f-272a348d660c/

를하고 괜찮 았는데 릴리스 버전을 실행할 때 디버거에서 실행할 때 제대로 작동하지 않았습니다.

+0

잘못된 코드를 게시하여 죄송합니다. 이제는 정확한 코드 –

+0

을 게시했습니다. 콘솔 출력 (예 : "사용자"시간에는 포함되지 않은 커널 WriteFile (CONOUT $) 호출)에 대부분 시간을 소비하기 때문에. –

+0

@Ben 디버그 모드에서 코드를 실행하면 시간이 표시되지 않는다는 내용의이 기사가 발견되었습니다. http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f -272a348d660c/ – Kiril

관련 문제