Ich musste die Ausführungszeit der einzelnen Funktionen innerhalb einer Bibliothek messen. Ich wollte nicht jeden Aufruf jeder Funktion mit einer Zeitmessfunktion umhüllen müssen, weil das hässlich ist und den Aufrufstapel vergrößert. Ich wollte auch nicht am Anfang und am Ende jeder Funktion einen Zeitmessungscode einfügen, weil das zu einem Chaos führt, wenn die Funktion zum Beispiel vorzeitig beendet wird oder Ausnahmen auslöst. Also habe ich einen Timer entwickelt, der seine eigene Lebensdauer verwendet, um die Zeit zu messen.
Auf diese Weise kann ich die Zeit messen, die ein Codeblock benötigte, indem ich einfach eines dieser Objekte zu Beginn des betreffenden Codeblocks (Funktion oder ein beliebiger Bereich) instanziiere und dann dem Destruktor der Instanz erlaube, die seit der Konstruktion verstrichene Zeit zu messen, wenn die Instanz den Bereich verlässt. Das vollständige Beispiel finden Sie unter aquí aber die Struktur ist sehr einfach:
template <typename clock_t = std::chrono::steady_clock>
struct scoped_timer {
using duration_t = typename clock_t::duration;
const std::function<void(const duration_t&)> callback;
const std::chrono::time_point<clock_t> start;
scoped_timer(const std::function<void(const duration_t&)>& finished_callback) :
callback(finished_callback), start(clock_t::now()) { }
scoped_timer(std::function<void(const duration_t&)>&& finished_callback) :
callback(finished_callback), start(clock_t::now()) { }
~scoped_timer() { callback(clock_t::now() - start); }
};
Die Struktur ruft Sie über den bereitgestellten Funktor zurück, wenn sie den Bereich verlässt, so dass Sie etwas mit den Zeitinformationen tun können (drucken oder speichern oder was auch immer). Wenn Sie etwas noch Komplexeres machen wollen, können Sie sogar std::bind
con std::placeholders
zu Callback-Funktionen mit mehreren Argumenten.
Hier ist ein kurzes Beispiel für die Anwendung:
void test(bool should_throw) {
scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
auto e = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed).count();
std::cout << "took " << e << "ms" << std::endl;
});
std::this_thread::sleep_for(std::chrono::seconds(1));
if (should_throw)
throw nullptr;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Wenn Sie mehr Sorgfalt walten lassen wollen, können Sie auch new
y delete
um den Timer explizit zu starten und zu stoppen, ohne sich auf Scoping zu verlassen, um es für Sie zu tun.
10 Stimmen
Ich verstehe die Frage nicht. Natürlich sind die Werte unterschiedlich. Dazwischen ist Zeit vergangen, also
time()
gibt einen anderen Wert zurück.1 Stimmen
Was meinen Sie mit "Ich verstehe nicht, warum die Werte im Vorher und Nachher unterschiedlich sind"? Sie erhalten die aktuelle Zeit (in Sekunden seit dem 1. Januar 1970) mit
time(NULL)
... das zweite Mal, wenn Sie es aufrufen, wird N Sekunden nach dem ersten und damit ... anders sein (es sei denn, was auch immer es ist Sie tun, dauert nicht eine Sekunde zu beenden ... in diesem Fall, es wird das gleiche wie das erste sein).1 Stimmen
Können Sie uns sagen, was gedruckt wird und wie lange es dauert, wenn Sie es mit einer Stoppuhr oder einer Wanduhr (oder einem Kalender) messen?
5 Stimmen
Entschuldigung, ich meine, dass beide Werte gleich sind. Ich habe meine Frage falsch geschrieben.
2 Stimmen
Siehe dieses Thema: stackoverflow.com/questions/275004/
0 Stimmen
@hap497 cool, aber was druckt es (und wie lange dauert es, wenn man es von Hand macht)?
0 Stimmen
Haben Sie schon einmal Folgendes gelesen open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
0 Stimmen
Möchten Sie messen Wanduhr Zeit (Zeitpunkt des Prozessendes - Zeitpunkt des Prozessbeginns), oder wollen Sie messen verbrauchte CPU-Zeit ? (Die Wanduhrzeit kann ein Bruchteil der CPU-Zeit bei Multithreading sein, und die CPU-Zeit kann ein Bruchteil der Wanduhrzeit sein, wenn Ihr Prozess auf E/A wartet.) Hierfür müssen Sie verschiedene Funktionen verwenden. Für letzteres ist es am einfachsten, Ihren Prozess unter der Kontrolle der
time
(keine Änderung des Quellcodes erforderlich); dadurch erhalten Sie auch die Zeit, die der Kernel für die Verarbeitung der E/A des Prozesses benötigt.0 Stimmen
Sie erleben vielleicht die Microsoft Minute .
0 Stimmen
Wenn einfach ist das Wichtigste: $
time ./MyProgram
(nur Linux). Referenz: levelup.gitconnected.com/ .0 Stimmen
time(NULL)
hat ein Ergebnis in Sekunden. Wenn das Programm weniger als eine Sekunde dauert, sind Start- und Endzeit gleich lang. Das Ergebnis von timersub ist eine Struktur mit ganzzahligen Sekunden und ganzzahligen Mikrosekunden (siehe man7.org/linux/man-pages/man2/settimeofday.2.html ) Man könnte es also ausdrucken mitprintf("**time taken = %ld.%06ld\n", diff.tv_sec, diff.tv_usec);
0 Stimmen
Beachten Sie, dass
tv_usec
ist Mikrosekunden nicht Nanosekunden. Dieu
wird oft anstelle von (Kleinbuchstabe mu) verwendet, da es in ASCII (nicht erweitert) nicht verfügbar ist, daher "usec" anstelle von "s".