2013-08-24 7 views
8

Ich versuche, einen Weg zu finden, Code zu schreiben, der genau die Zeit ermitteln kann, die benötigt wird, um eine Suche auf einem BST durchzuführen. Zurzeit verwende ich die Zeit und die Gesamtzahl der Elemente liegt in der Größenordnung von 10^5. Es sieht in etwa so aus: -Hochgenaue Zeitmessung in C

clock_t begin, end; 
begin = clock(); 
... 
... 
... 
end = clock(); 
difference = (end-begin)/CLOCKS_PER_SECOND; 

Allerdings gibt mir das nicht die Präzision, nach der ich suche. Gibt es noch andere libc-Funktionen, die ich verwenden könnte?

+0

Ich denke gelesen: 'difftime (,)' –

+0

möglich Duplikat von [in Millisekunden die aktuelle Uhrzeit Erste] (http://stackoverflow.com/questions/3756323/getting-the-current-time -in-Millisekunden) –

+0

Duplikat von http://stackoverflow.com/questions/6749621/high-resolution-timer-in-linux und viele andere Fragen hier –

Antwort

0

BST? Welche Art von Präzision willst du? Die Division durch CLOCKS_PER_SECOND mit 10^6 auf einem 32-Bit-System sollte eine 6-stellige Genauigkeit ergeben?

Wirf das Ergebnis auf ein Double?

versuchen

difference = (double)(end-begin)/CLOCKS_PER_SECOND; 

Beachten Sie, dass Unterschied sollte eine doppelte halten können.

+0

'Uhr()' ist präzise, ​​aber es ist nicht sehr genau. Es ist in der Regel nur bis etwa 50 Millisekunden genau. Und unter Linux misst es auch CPU-Zeit statt Wall-Time. – Mysticial

+0

Ja, ich habe ein Double verwendet - ich habe eine Ausgabe ähnlich wie 0,000000 –

+0

@Mysticial Ist nicht CPU-Zeit, was hier benötigt wird? Die Zeit, die benötigt wird, um die BST zu durchsuchen, sollte nicht die Zeit enthalten, die von anderen Prozessen verbraucht wird, was die Wandzeit für Sie bedeuten würde. –

2

Um Ihren Algorithmus zu benchmarken, müssen Sie einige Wiederholungen durchführen, um in den Bereich von mindestens hunderten von Millisekunden zu gelangen. (Dies ist Standard). Um einen Algorithmus zu benchmarken, der nur im Benutzerbereich stattfindet (kein Threading, Systemaufrufe usw.), möchten Sie getrusage(RUSAGE_SELF, &r) verwenden und den Wert r.ru_utime verwenden, der Sekunden und Mikrosekunden enthält.

0

Qt hat QElapsedTimer unterstützt die Messung bis zu Nanosekunden. Ich kann nicht sagen, wie genau es ist, IIRC verwendet verschiedene Implementierungen auf verschiedenen Plattformen. Leider ist es C++, was Ihnen vielleicht nicht passt. Auch:

Auf Plattformen, die nicht Nanosekunde Auflösung bieten, den Wert zurückgegeben wird die beste Schätzung zur Verfügung.

Die clock() Funktion ist für grobe Messungen in Ordnung, aber sie arbeitet im Millisekundenbereich. Im Gegensatz zu seinem Namen glaube ich nicht, dass es in CPU-Takten misst, da moderne Taktfrequenzen der Prozessoren ziemlich variieren können, was es unmöglich macht, die tatsächliche Zeit genau auf der Basis von CPU-Takten genau zu bestimmen. IMO dieses Konzept stammt aus den Tagen, als CPU-Frequenzen konstant waren, gab es keine Power-Management, keine "Turbo Boost" automatische Übertaktung oder was auch immer.

EDIT: Auch fanden diese (time.h):

int clock_gettime(clockid_t clk_id, struct timespec *tp); 

    ... and the target struct... 

    struct timespec { 
      time_t tv_sec;  /* seconds */ 
      long  tv_nsec;  /* nanoseconds */ 
    }; 

... and the clock options... 


CLOCK_REALTIME 
    System-wide realtime clock. Setting this clock requires appropriate privileges. 
CLOCK_MONOTONIC 
    Clock that cannot be set and represents monotonic time since some unspecified starting point. 
CLOCK_PROCESS_CPUTIME_ID 
    High-resolution per-process timer from the CPU. 
CLOCK_THREAD_CPUTIME_ID 
    Thread-specific CPU-time clock. 
2

Wenn Ihre Bibliothek unterstützt, C11 hat timespec_get(), die auf Nanosekunden messen wird, je nach Auflösung Systemuhr.

0

Was Sie tun, ist ziemlich ähnlich zu dem, was ich in letzter Zeit getan habe.

Ich denke, dass die int gettimeofday(struct timeval *tv, struct timezone *tz); Funktion Ihren Bedürfnissen entspricht. Die Zeitinformation würde in die struct timeval tv eingegeben, die die Zeit in Sekunden und Mikrosekunden erhält.Die struct timeval von der man-Seite:

struct timeval { 
       time_t  tv_sec;  /* seconds */ 
       suseconds_t tv_usec; /* microseconds */ 
}; 

Ein kurzes Beispiel für die Zeitmessung mit gettimeofday:

struct timeval time; 
if(gettimeofday(&time, 0)) return -1; 

long cur_time = 1000000 * time.tv_sec + time.tv_usec; 
double sec = cur_time/1000000.0; 

Einem längeren Beispiel wurde vereinfacht und leicht als C++ Klasse für die bequeme Nutzung gewickelt. Der Code wurde auf meinen GitHub gesetzt: https://github.com/lulyon/LinuxTimeCounter, was in einem realen Projekt verwendet wird.