2010-04-05 9 views
5

Ich bin neu in C# Welt. Ich versuche die Zeit zu berechnen, die ein Algorithmus für den Vergleich benötigt. Der folgende Code misst die verstrichene Zeit vom Aufruf einer Subroutine bis zur Rückkehr der Subroutine zum Hauptprogramm. Dieses Beispiel stammt aus "Datenstrukturen durch C#" von Michael McMillan. Nach dem Ausführen dieses Programms ist die Ausgabe Time = 0, was falsch ist. Das Programm scheint logisch korrekt zu sein. Kann mir jemand helfen. Im Folgenden finden Sie den CodeBenötigte Zeit für einen Prozess

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

Führen Sie es nicht im Debug-Modus (nach einigen Online-Ressourcen). – Kiril

+0

Ich hatte das gleiche Problem! Ben Voigt hat recht, man kann nicht davon ausgehen, dass der Thread mit dem Index 0 (INDEX, nicht Thread ID !!!) derjenige ist, an dem Sie interessiert sind. Ich benutze nun ein PInvoke um GetCurrentThreadId() zu bekommen um die richtige Thread ID zu bekommen . Dann durchlaufe ich alle Threads und suche nach dem mit dieser Thread-ID. – Jane

Antwort

3

Die Stopwatch class ist dafür ausgelegt.

UserProcessorTime beginnt nicht mit der Auflösung, die zum Messen der Zählung auf 100000 in einer for-Schleife erforderlich ist. Ihre WriteLine-Aufrufe werden in der Benutzerzeit nicht berücksichtigt, da es sich um E/A-Zeit handelt. Ihr Code wird möglicherweise nicht in Thread 0 ausgeführt. Die Benutzerzeit wird nur bei Kontextwechsel aktualisiert. Wenn Sie startTime drucken, ändern Sie den gespeicherten Wert. Es gibt wahrscheinlich noch andere Dinge, die schiefgehen können, an die ich nicht gedacht habe.

Ich empfehle dringend die Verwendung der Stoppuhr-Klasse, die die Leistungsindikatoren der CPU nutzt.

+0

@Ben das OP fragt, warum dieses Beispiel nicht funktioniert. – Kiril

+0

Sehr geehrter Ben, ich werde Ihnen mitteilen, wenn Sie sich auf den richtigen Code beziehen können, den ich gerade bearbeitet habe. Danke –

+0

In der .NET-Umgebung läuft jedes Programm innerhalb der Anwendungsdomäne. Dadurch kann das Betriebssystem verschiedene Programme gleichzeitig ausführen. Innerhalb eines Prozesses wird ein Programm oder ein Teil eines Programms innerhalb eines Threads ausgeführt. Die Ausführungszeit für ein Programm wird vom Betriebssystem über Threads vergeben.Wenn wir den Code für ein Programm zeitlich festlegen, möchten wir sicherstellen, dass wir nur den Code innerhalb des für unser Programm zugewiesenen Prozesses zeitlich einteilen, und nicht andere vom Betriebssystem ausgeführte Aufgaben. Unter Verwendung der Stoppuhrklasse würden wir eine andere Zeit in die Gesamtzeit einbeziehen. –

2

Du hast nicht die Timing Klasse überall in Ihrem Haupt-Funktion verwenden und ich sehe nicht, wo Sie die Zeit entweder drucken. Ist dies der EXACT Code, den Sie ausführen?

Update per neuem Code:

Sie führen Sie es nicht im Debug-Modus ... Ihre Release-Version bauen und dann die ausführbare Datei manuell ausführen: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f-272a348d660c/

ich Ihren Code getestet und es funktioniert gut wenn ich die Release-Version ausführte, aber als ich es im Debugger ausführte, funktionierte es nicht richtig.

+0

Entschuldigung für das Posten des falschen Codes. Jetzt habe ich genauen Code geschrieben –

+0

Weil die meiste Zeit ausgegeben wird Konsolenausgabe - d. H. Ein Kernel WriteFile (CONOUT $) Aufruf, der nicht in "Benutzer" Zeit enthalten ist. –

+0

@Ben Ich fand diesen Artikel, der vorschlägt, dass das Ausführen des Codes im Debug-Modus die Uhrzeit nicht anzeigen würde: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/3f10a46a-ba03-4f5a-9d1f -272a348d660c/ – Kiril

Verwandte Themen