Wie stempel ich zweimal t1 und t2 und erhalte die Differenz in Millisekunden in C?
Zeitstempel in der Programmiersprache C
Chris_45
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
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 ein1s
Auflösung; die Präzision vonclock()
ist normalerweise so hoch wie möglich, misst aber die Laufzeit und nicht die Datumszeit– Christoph
18. September 2009 um 18:25 Uhr
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.
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(<ime);
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
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
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
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
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