Zeitstempel in der Programmiersprache C

Lesezeit: 7 Minuten

Benutzer-Avatar
Chris_45

Wie stempel ich zweimal t1 und t2 und erhalte die Differenz in Millisekunden in C?

  • Mit Standard-C allein geht das nicht. Die möglichen Lösungen, die Sie haben, werden für Linux, Windows, Mobiltelefone, Registrierkassen, …, Mikrowellenherde, … unterschiedlich sein.

    – pmg

    18. September 2009 um 13:26 Uhr

  • @Christoph: Sowohl time() als auch clock() können -1 (in den entsprechenden Typ umgewandelt) zurückgeben, um anzuzeigen, dass die Funktion in dieser Implementierung nicht verfügbar ist … und time() hat, wenn verfügbar, eine Auflösung von 1 Sekunde oder schlechter. Ich habe den Standard durchgelesen, aber keine harten Grenzen für die Funktion clock() gefunden

    – pmg

    18. September 2009 um 17:58 Uhr

  • Auf der Linux-Handbuchseite: “Beachten Sie, dass die Zeit umlaufen kann. Auf einem 32-Bit-System, auf dem CLOCKS_PER_SEC gleich 1000000 ist, gibt diese Funktion ungefähr alle 72 Minuten denselben Wert zurück.” Um die CPU-Zeit zu erhalten, ist getrusage() besser, obwohl clock Teil von ANSI C ist, aber getrusage/gettimeofday() nicht.

    – Benutzer172818

    18. September 2009 um 18:58 Uhr

Dadurch erhalten Sie die Zeit in Sekunden + Mikrosekunden

#include <sys/time.h>
struct timeval tv;
gettimeofday(&tv,NULL);
tv.tv_sec // seconds
tv.tv_usec // microseconds

Benutzer-Avatar
Christoph

Standard-C99:

#include <time.h>

time_t t0 = time(0);
// ...
time_t t1 = time(0);
double datetime_diff_ms = difftime(t1, t0) * 1000.;

clock_t c0 = clock();
// ...
clock_t c1 = clock();
double runtime_diff_ms = (c1 - c0) * 1000. / CLOCKS_PER_SEC;

Die Genauigkeit der Typen ist implementierungsdefiniert, dh die datetime-Differenz kann nur volle Sekunden zurückgeben.

  • Die datetime-Differenz gibt bestenfalls volle Sekunden zurück. Wenn ich den Standard richtig interpretiert habe, ist es nicht garantiert, dass time() jede Sekunde neue Werte zurückgibt, wenn es nicht (time_t)-1 zurückgibt: Es kann beispielsweise eine Auflösung von 5 Sekunden oder 1 Minute haben.

    – pmg

    18. September 2009 um 18:04 Uhr

  • @pmg: Die Genauigkeit ist implementierungsdefiniert, zB auf meinem System time() hat ein 1s Auflösung; die Präzision von clock() ist normalerweise so hoch wie möglich, misst aber die Laufzeit und nicht die Datumszeit

    – Christoph

    18. September 2009 um 18:25 Uhr

Benutzer-Avatar
darron

Wenn Sie die verstrichene Zeit ermitteln möchten, funktioniert diese Methode, solange Sie den Computer zwischen Start und Ende nicht neu starten.

Verwenden Sie unter Windows GetTickCount(). Hier ist wie:

DWORD dwStart = GetTickCount();
...
... process you want to measure elapsed time for
...
DWORD dwElapsed = GetTickCount() - dwStart;

dwVergangen ist jetzt die Anzahl der verstrichenen Millisekunden.

Verwenden Sie unter Linux Uhr() und CLOCKS_PER_SEC um dasselbe zu tun.

Wenn Sie Zeitstempel benötigen, die Neustarts oder PCs überdauern (was in der Tat eine recht gute Synchronisierung erfordern würde), verwenden Sie die anderen Methoden (gettimeofday()).

Außerdem können Sie zumindest unter Windows eine viel bessere Zeitauflösung als die Standardzeit erreichen. Wenn Sie GetTickCount() in einer engen Schleife aufrufen, sehen Sie normalerweise, dass es jedes Mal um 10-50 springt, wenn es sich ändert. Das liegt an dem Zeitquantum, das vom Windows-Thread-Scheduler verwendet wird. Dies ist mehr oder weniger die Zeit, die jeder Thread ausgeführt werden muss, bevor zu etwas anderem gewechselt wird. Wenn Sie Folgendes tun:

timeBeginPeriod(1);

zu Beginn Ihres Programms oder Prozesses und ein:

timeEndPeriod(1);

Am Ende ändert sich das Quantum auf 1 ms, und Sie erhalten eine viel bessere Zeitauflösung beim Aufruf von GetTickCount(). Dies ändert jedoch geringfügig die Art und Weise, wie Ihr gesamter Computer Prozesse ausführt. Denken Sie also daran. Windows Media Player und viele andere Dinge tun dies jedoch sowieso routinemäßig, sodass ich mir darüber keine allzu großen Sorgen mache.

Ich bin mir sicher, dass es unter Linux wahrscheinlich eine Möglichkeit gibt, dasselbe zu tun (wahrscheinlich mit viel besserer Kontrolle oder vielleicht mit Quanten unter einer Millisekunde), aber ich musste das unter Linux noch nicht tun.

Benutzer-Avatar
AKM Mahmudul Hoque

/*
 Returns the current time.
*/

char *time_stamp(){

char *timestamp = (char *)malloc(sizeof(char) * 16);
time_t ltime;
ltime=time(NULL);
struct tm *tm;
tm=localtime(&ltime);

sprintf(timestamp,"%04d%02d%02d%02d%02d%02d", tm->tm_year+1900, tm->tm_mon, 
    tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
return timestamp;
}


int main(){

printf(" Timestamp: %s\n",time_stamp());
return 0;

}

Ausgabe: Zeitstempel: 20110912130940 // 2011 Sep 12 13:09:40

Benutzer-Avatar
Rechnung

Verwenden Sie den Code von @ Arkaitz Jimenez, um zwei Zeitwerte zu erhalten:

#include <sys/time.h>
//...
struct timeval tv1, tv2, diff;

// get the first time:
gettimeofday(&tv1, NULL);

// do whatever it is you want to time
// ...

// get the second time:
gettimeofday(&tv2, NULL);

// get the difference:

int result = timeval_subtract(&diff, &tv1, &tv2);

// the difference is storid in diff now.

Beispielcode für timeval_subtract finden Sie unter Diese Internetseite:

 /* Subtract the `struct timeval' values X and Y,
    storing the result in RESULT.
    Return 1 if the difference is negative, otherwise 0.  */

 int
 timeval_subtract (result, x, y)
      struct timeval *result, *x, *y;
 {
   /* Perform the carry for the later subtraction by updating y. */
   if (x->tv_usec < y->tv_usec) {
     int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
     y->tv_usec -= 1000000 * nsec;
     y->tv_sec += nsec;
   }
   if (x->tv_usec - y->tv_usec > 1000000) {
     int nsec = (x->tv_usec - y->tv_usec) / 1000000;
     y->tv_usec += 1000000 * nsec;
     y->tv_sec -= nsec;
   }

   /* Compute the time remaining to wait.
      tv_usec is certainly positive. */
   result->tv_sec = x->tv_sec - y->tv_sec;
   result->tv_usec = x->tv_usec - y->tv_usec;

   /* Return 1 if result is negative. */
   return x->tv_sec < y->tv_sec;
 }

  • Der Code in timeval_subtract ist böse, weil er den Eingabewert y modifiziert. Es wäre nicht schlecht, wenn die Eingaben zwei struct timeval-Werte wären – im Gegensatz zu Zeigern. Aber wenn Sie ‘x – y’ auswerten, erwarten Sie normalerweise nicht, dass die Berechnung den in ‘y’ gespeicherten Wert ändert.

    – Jonathan Leffler

    18. September 2009 um 13:33 Uhr

  • @Jonathan, stimmt. Eine einfache Änderung in eine Pass-by-Copy-Implementierung würde dieses Problem jedoch lösen

    – Glen

    18. September 2009 um 13:43 Uhr

  • Ich stimme zu. Ich würde es reparieren, aber ich kann nicht überprüfen, ob meine Änderungen im Moment kompiliert werden, also dachte ich, ich würde es so lassen, wie es ist.

    – Rechnung

    18. September 2009 um 13:55 Uhr

Benutzer-Avatar
n00pster

wie wäre es mit dieser Lösung? So etwas habe ich bei meiner Suche nicht gesehen. Ich versuche, eine Teilung zu vermeiden und die Lösung einfacher zu machen.

   struct timeval cur_time1, cur_time2, tdiff;

   gettimeofday(&cur_time1,NULL);
   sleep(1);
   gettimeofday(&cur_time2,NULL);

   tdiff.tv_sec = cur_time2.tv_sec - cur_time1.tv_sec;
   tdiff.tv_usec = cur_time2.tv_usec + (1000000 - cur_time1.tv_usec);

   while(tdiff.tv_usec > 1000000)
   {
      tdiff.tv_sec++;
      tdiff.tv_usec -= 1000000;
      printf("updated tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec);
   }

   printf("end tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec);

  • Der Code in timeval_subtract ist böse, weil er den Eingabewert y modifiziert. Es wäre nicht schlecht, wenn die Eingaben zwei struct timeval-Werte wären – im Gegensatz zu Zeigern. Aber wenn Sie ‘x – y’ auswerten, erwarten Sie normalerweise nicht, dass die Berechnung den in ‘y’ gespeicherten Wert ändert.

    – Jonathan Leffler

    18. September 2009 um 13:33 Uhr

  • @Jonathan, stimmt. Eine einfache Änderung in eine Pass-by-Copy-Implementierung würde dieses Problem jedoch lösen

    – Glen

    18. September 2009 um 13:43 Uhr

  • Ich stimme zu. Ich würde es reparieren, aber ich kann nicht überprüfen, ob meine Änderungen im Moment kompiliert werden, also dachte ich, ich würde es so lassen, wie es ist.

    – Rechnung

    18. September 2009 um 13:55 Uhr

Benutzer-Avatar
Gemeinschaft

Beachten Sie auch die Interaktionen zwischen clock() und usleep(). usleep() hält das Programm an und clock() misst nur die Zeit, in der das Programm läuft.

Es ist möglicherweise besser, gettimeofday() wie hier erwähnt zu verwenden

1353000cookie-checkZeitstempel in der Programmiersprache C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy