So berechnen Sie einen Zeitunterschied in C ++

94

Was ist der beste Weg, um einen Zeitunterschied in C ++ zu berechnen? Ich stelle die Ausführungsgeschwindigkeit eines Programms ein, daher interessieren mich Millisekunden. Besser noch, Sekunden. Millisekunden.

Die akzeptierte Antwort funktioniert, muss jedoch ctime oder time.h enthalten, wie in den Kommentaren angegeben.

Jack BeNimble
quelle
Dupe, kann aber momentan nicht verlinken
Robert Gould
2
Die Abstimmung zum Abschluss war zu wenig, zu spät. Ich habe eine funktionierende Antwort bekommen. Trotzdem netter Versuch. Übrigens konnte ich auch keinen Link finden.
Jack BeNimble
Es ist für Fenster? Versuchen Sie dann GetTickCount (Windows API)
aJ.
5
Robert: Zum Glück, weil der neue Beitrag mehrere weitere Antworten erlaubte, von denen ich eine ausgewählt habe. Im Ernst, ich frage mich, welchen Wert es hat, einen Dup-Post zu schließen. Was wäre, wenn einige Lösungen in der ersten nicht erwähnt würden? Neue Technologien entwickelt? Sie können es aufgrund unterschiedlicher Überschriften nicht finden?
Jack BeNimble
2
@JackBeNimble Nachdem ich ein paar "Dups" erhalten habe, die nicht gerade Dups waren (vielleicht Leute, die die Frage vielleicht schnell gelesen und markiert haben, weil sie einer anderen Frage ähnlich klingt), stimme ich Ihrem Punkt voll und ganz zu ... wahrscheinlich ein Punkt für den Austausch von Meta-Stacks: o
code_fodder

Antworten:

121

Siehe std::clock()Funktion.

const clock_t begin_time = clock();
// do something
std::cout << float( clock () - begin_time ) /  CLOCKS_PER_SEC;

Wenn Sie die Ausführungszeit für sich selbst berechnen möchten (nicht für den Benutzer), ist es besser, dies in Taktstrichen (nicht in Sekunden) zu tun.

BEARBEITEN:
verantwortliche Header-Dateien - <ctime>oder<time.h>

Bayda
quelle
4
Beachten Sie, dass die Genauigkeit von clock () viel schlechter sein kann, obwohl clock () einige Millisekunden zurückgibt. In Windows beträgt die Genauigkeit der Funktion clock () ungefähr 40 ms.
John Dibling
2
Ich habe es auf Mac 10.7 versucht. Meine App führt eine 100-MB-Datei in 15 Sekunden aus, aber die Differenzzeit beträgt 61 Sekunden. Nicht viel zu gebrauchen. Ich denke, time () ist wahrscheinlich besser.
Miek
5
clock()Gibt die vom Programm verbrauchte CPU-Zeit zurück. Wenn das Programm also parallel ausgeführt wird, ist die von der Funktion zurückgegebene Zeit die Summe der
Ameer Jewdaki
3
Diese Antwort ist irreführend, da sie die CPU-Zeit und nicht die tatsächliche Wanduhrzeit anzeigt.
Ultraviolett
1
Ich muss hier Ultraviolett zustimmen. Die Verwendung der CPU-Zeit zum Messen der Geschwindigkeit eines Programms scheint das Falsche zu sein. OP sollte dies als die richtige Antwort markieren. IMO sollten Sie std :: chrono :: stetige_uhr :: jetzt () verwenden, wie durch mehrere Antworten im folgenden Thread beschrieben. Stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun
37

Wenn Sie C ++ 11 verwenden, finden Sie hier einen einfachen Wrapper (siehe diese Zusammenfassung ):

#include <iostream>
#include <chrono>

class Timer
{
public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const { 
        return std::chrono::duration_cast<second_>
            (clock_::now() - beg_).count(); }

private:
    typedef std::chrono::high_resolution_clock clock_;
    typedef std::chrono::duration<double, std::ratio<1> > second_;
    std::chrono::time_point<clock_> beg_;
};

Oder für c ++ 03 auf * nix:

#include <iostream>
#include <ctime>

class Timer
{
public:
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }

    double elapsed() {
        clock_gettime(CLOCK_REALTIME, &end_);
        return end_.tv_sec - beg_.tv_sec +
            (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
    }

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }

private:
    timespec beg_, end_;
};

Anwendungsbeispiel:

int main()
{
    Timer tmr;
    double t = tmr.elapsed();
    std::cout << t << std::endl;

    tmr.reset();
    t = tmr.elapsed();
    std::cout << t << std::endl;
    return 0;
}
Gongzhitaao
quelle
2
Eine andere Option wäre die Verwendung von boost :: chrono anstelle des C ++ 11 STL std :: chrono-Namespace. Vielen Dank für Ihren Code.
Didac Perez Parera
Achtung: Dies funktioniert nicht, wenn der Benutzer seine Zeit zwischen Timer()und dem Aufruf auf elapsed()if ändert !std::chrono::high_resolution_clock::is_steady- was unter Linux der Fall ist!
Jhasse
30

Ich würde ernsthaft über die Verwendung von Boost nachdenken, insbesondere boost :: posix_time :: ptime und boost :: posix_time :: time_duration (unter http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time) .html ).

Es ist plattformübergreifend, einfach zu bedienen und bietet meiner Erfahrung nach die höchste Zeitauflösung, die ein Betriebssystem bietet. Möglicherweise auch sehr wichtig; Es bietet einige sehr nette E / A-Operatoren.

Um damit den Unterschied in der Programmausführung zu berechnen (in Mikrosekunden; wahrscheinlich Overkill), würde es ungefähr so ​​aussehen [Browser geschrieben, nicht getestet]:

ptime time_start(microsec_clock::local_time());
//... execution goes here ...
ptime time_end(microsec_clock::local_time());
time_duration duration(time_end - time_start);
cout << duration << '\n';
Jeremy CD
quelle
3
Boost local_time () ist jedoch nicht monoton und sollte daher nicht zum Messen von Zeitraffern verwendet werden. Ich habe keinen Weg gefunden, von Boost aus auf monotone Zeit zuzugreifen.
Gatopeich
26

Ich habe diese Antwort hinzugefügt, um zu verdeutlichen, dass die akzeptierte Antwort die CPU-Zeit anzeigt, die möglicherweise nicht die gewünschte Zeit ist. Denn laut Referenz gibt es CPU-Zeit und Wanduhrzeit . Die Wanduhrzeit ist die Zeit, die die tatsächlich verstrichene Zeit unabhängig von anderen Bedingungen wie der von anderen Prozessen gemeinsam genutzten CPU anzeigt. Zum Beispiel habe ich mehrere Prozessoren verwendet, um eine bestimmte Aufgabe zu erledigen, und die CPU-Zeit betrug 18 Sekunden, wobei die tatsächliche Wanduhrzeit tatsächlich 2 Sekunden dauerte .

Um die tatsächliche Zeit zu erhalten, die Sie tun,

#include <chrono>

auto t_start = std::chrono::high_resolution_clock::now();
// the work...
auto t_end = std::chrono::high_resolution_clock::now();

double elapsed_time_ms = std::chrono::duration<double, std::milli>(t_end-t_start).count();
Ultraviolett
quelle
2
Ohne diese Antwort hätte ich std :: chrono nicht verwenden können, danke!
Giles
13

Boost 1.46.0 und höher enthält die Chrono- Bibliothek:

Die Klasse thread_clock bietet Zugriff auf die reale Thread-Wanduhr, dh die reale CPU-Zeituhr des aufrufenden Threads. Die relative aktuelle Zeit des Threads kann durch Aufrufen von thread_clock :: now () ermittelt werden.

#include <boost/chrono/thread_clock.hpp>
{
...
    using namespace boost::chrono;
    thread_clock::time_point start = thread_clock::now();
    ...
    thread_clock::time_point stop = thread_clock::now();  
    std::cout << "duration: " << duration_cast<milliseconds>(stop - start).count() << " ms\n";
Gabi Davar
quelle
7
Außerdem verfügt C ++ 11 über einen std::chronoNamespace mit fast demselben Inhalt.
Ulidtko
12

In Windows: Verwenden Sie GetTickCount

//GetTickCount defintition
#include <windows.h>
int main()
{

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

    cout<<"Time difference is "<<(dw2-dw1)<<" milliSeconds"<<endl;

}
aJ.
quelle
8

Sie können auch die clock_gettime verwenden . Diese Methode kann verwendet werden, um zu messen:

  1. Systemweite Echtzeituhr
  2. Systemweite monotone Uhr
  3. CPU-Zeit pro Prozess
  4. Pro Prozess Thread-CPU-Zeit

Der Code lautet wie folgt:

#include < time.h >
#include <iostream>
int main(){
  timespec ts_beg, ts_end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end);
  std::cout << (ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec) / 1e9 << " sec";
}

`

Richard
quelle
6

Nur für den Fall, dass Sie unter Unix arbeiten, können timeSie die Ausführungszeit abrufen:

$ g++ myprog.cpp -o myprog
$ time ./myprog
Fengshaun
quelle
5

Nur eine Randnotiz: Wenn Sie unter Windows arbeiten und wirklich Präzision benötigen, können Sie QueryPerformanceCounter verwenden . Es gibt Ihnen Zeit in (möglicherweise) Nanosekunden .

v3.
quelle
5

Für mich ist der einfachste Weg:

#include <boost/timer.hpp>

boost::timer t;
double duration;

t.restart();
/* DO SOMETHING HERE... */
duration = t.elapsed();

t.restart();
/* DO OTHER STUFF HERE... */
duration = t.elapsed();

Mit diesem Code müssen Sie nicht den Klassiker machen end - start.

Genießen Sie Ihren Lieblingsansatz.

user1823890
quelle
ist t.elapsed () in sec oder mili-sec?
mkuse
4

Ermitteln Sie die Systemzeit am Anfang und am Ende in Millisekunden und subtrahieren Sie sie.

Um die Anzahl der Millisekunden seit 1970 in POSIX zu ermitteln, schreiben Sie:

struct timeval tv;

gettimeofday(&tv, NULL);
return ((((unsigned long long)tv.tv_sec) * 1000) +
        (((unsigned long long)tv.tv_usec) / 1000));

Um die Anzahl der Millisekunden seit 1601 unter Windows zu ermitteln, schreiben Sie:

SYSTEMTIME systime;
FILETIME filetime;

GetSystemTime(&systime);
if (!SystemTimeToFileTime(&systime, &filetime))
    return 0;

unsigned long long ns_since_1601;
ULARGE_INTEGER* ptr = (ULARGE_INTEGER*)&ns_since_1601;

// copy the result into the ULARGE_INTEGER; this is actually
// copying the result into the ns_since_1601 unsigned long long.
ptr->u.LowPart = filetime.dwLowDateTime;
ptr->u.HighPart = filetime.dwHighDateTime;

// Compute the number of milliseconds since 1601; we have to
// divide by 10,000, since the current value is the number of 100ns
// intervals since 1601, not ms.
return (ns_since_1601 / 10000);

Wenn Sie die Windows-Antwort so normalisieren möchten, dass sie auch die Anzahl der Millisekunden seit 1970 zurückgibt, müssen Sie Ihre Antwort um 11644473600000 Millisekunden anpassen. Dies ist jedoch nicht erforderlich, wenn Sie sich nur um die verstrichene Zeit kümmern.

Jared Oberhaus
quelle
4

Wenn Sie verwenden:

tstart = clock();

// ...do something...

tend = clock();

Dann benötigen Sie Folgendes, um die Zeit in Sekunden zu ermitteln:

time = (tend - tstart) / (double) CLOCKS_PER_SEC;
Robert White
quelle
0

Dies scheint für Intel Mac 10.7 gut zu funktionieren:

#include <time.h>

time_t start = time(NULL);


    //Do your work


time_t end = time(NULL);
std::cout<<"Execution Time: "<< (double)(end-start)<<" Seconds"<<std::endl;
Miek
quelle