Sous Windows, clock()
renvoie le temps en millisecondes, mais sur cette machine Linux sur laquelle je travaille, il est arrondi au millier le plus proche. La précision est donc au "deuxième" niveau et non aux millisecondes. niveau.
J'ai trouvé une solution avec Qt en utilisant la classe QTime
, en instanciant un objet et en appelant start()
puis en appelant elapsed()
pour obtenir le nombre de millisecondes écoulées.
J'ai eu un peu de chance parce que je travaille avec Qt pour commencer, mais j'aimerais une solution qui ne repose pas sur des bibliothèques tierces,
N'y a-t-il aucun moyen standard de faire cela?
MISE À JOUR
S'il vous plaît ne recommande pas Boost ..
Si Boost et Qt peuvent le faire, ce n'est sûrement pas magique, il doit y avoir quelque chose de standard qu'ils utilisent!
Vous pouvez utiliser gettimeofday au début et à la fin de votre méthode, puis différencier les deux structures de retour. Vous obtiendrez une structure comme celle-ci:
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
}
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
struct timeval start, end;
long mtime, seconds, useconds;
gettimeofday(&start, NULL);
usleep(2000);
gettimeofday(&end, NULL);
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
printf("Elapsed time: %ld milliseconds\n", mtime);
return 0;
}
Veuillez noter que clock
ne pas mesure l'heure de l'horloge murale. Cela signifie que si votre programme prend 5 secondes, clock
ne mesurera pas nécessairement 5 secondes, mais pourrait en faire plus (votre programme pourrait exécuter plusieurs threads et pourrait donc consommer plus de CPU que de temps réel) ou moins. Il mesure une approximation de temps de calcul utilisé. Pour voir la différence, considérons ce code
#include <iostream>
#include <ctime>
#include <unistd.h>
int main() {
std::clock_t a = std::clock();
sleep(5); // sleep 5s
std::clock_t b = std::clock();
std::cout << "difference: " << (b - a) << std::endl;
return 0;
}
Il sort sur mon système
$ difference: 0
Parce que tout ce que nous faisions était dormir et ne pas utiliser de temps processeur! Cependant, en utilisant gettimeofday
nous obtenons ce que nous voulons (?)
#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>
int main() {
timeval a;
timeval b;
gettimeofday(&a, 0);
sleep(5); // sleep 5s
gettimeofday(&b, 0);
std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
return 0;
}
Sorties sur mon système
$ difference: 5
Si vous avez besoin de plus de précision mais que vous voulez obtenir temps de calcul, vous pouvez envisager d'utiliser la fonction getrusage
.
Je recommande également les outils proposés par Boost. Soit le minuteur Boost mentionné, soit piratez quelque chose hors de Boost.DateTime ou il y a une nouvelle bibliothèque proposée dans le bac à sable - Boost.Chrono : Ce dernier remplacera le minuteur et comportera:
duration
time_point
system_clock
monotonic_clock
high_resolution_clock
timer
, avec typedefs: system_timer
monotonic_timer
high_resolution_timer
process_clock
, en capturant les temps réels, CPU utilisateur et système.process_timer
, capture des temps réels écoulés, de la CPU utilisateur et des temps système.run_timer
, rapports pratiques de | process_timer | résultats.Voici la source de la liste des fonctionnalités
J'ai écrit une classe Timer
basée sur réponse de CTT . Il peut être utilisé de la manière suivante:
Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);
Voici sa mise en oeuvre:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;
class Timer {
private:
timeval startTime;
public:
void start(){
gettimeofday(&startTime, NULL);
}
double stop(){
timeval endTime;
long seconds, useconds;
double duration;
gettimeofday(&endTime, NULL);
seconds = endTime.tv_sec - startTime.tv_sec;
useconds = endTime.tv_usec - startTime.tv_usec;
duration = seconds + useconds/1000000.0;
return duration;
}
static void printTime(double duration){
printf("%5.6f seconds\n", duration);
}
};
Si vous n'avez pas besoin que le code soit portable sur les anciens ordinateurs, vous pouvez utiliser clock_gettime (), qui vous donnera l'heure en nanosecondes (si votre processeur prend en charge cette résolution). C'est POSIX, mais à partir de 2001.
clock () a une résolution souvent moche. Si vous voulez mesurer le temps au niveau de la milliseconde, une solution consiste à utiliser clock_gettime (), comme expliqué dans cette question.
(N'oubliez pas que vous devez créer un lien avec -lrt sous Linux).
Avec C++ 11 et std::chrono::high_resolution_clock
tu peux le faire:
#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;
int main()
{
std::chrono::milliseconds three_milliseconds{3};
auto t1 = Clock::now();
std::this_thread::sleep_for(three_milliseconds);
auto t2 = Clock::now();
std::cout << "Delta t2-t1: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
<< " milliseconds" << std::endl;
}
Sortie:
Delta t2-t1: 3 milliseconds
Lien vers la démo: http://cpp.sh/2zdt
clock () ne renvoie pas des millisecondes ou des secondes sous Linux. Généralement, clock () renvoie des microsecondes sur un système Linux. La bonne façon d'interpréter la valeur renvoyée par clock () consiste à la diviser par CLOCKS_PER_SEC pour déterminer le temps écoulé.
Dans le standard POSIX, clock
a sa valeur de retour définie en fonction du symbole CLOCKS_PER_SEC et une implémentation est libre de le définir de manière appropriée. Sous Linux, j'ai eu de la chance avec la fonction times()
.
gettimeofday - le problème est que vous pouvez avoir des valeurs plus basses si vous modifiez votre horloge matérielle (avec NTP par exemple) Boost - non disponible pour cette horloge de projet () - renvoie généralement un entier de 4 octets, ce qui signifie que c'est une faible capacité, et après un certain temps, il renvoie des nombres négatifs.
Je préfère créer ma propre classe et mettre à jour toutes les 10 millisecondes. Cette méthode est donc plus flexible et je peux même l'améliorer pour avoir des abonnés.
class MyAlarm {
static int64_t tiempo;
static bool running;
public:
static int64_t getTime() {return tiempo;};
static void callback( int sig){
if(running){
tiempo+=10L;
}
}
static void run(){ running = true;}
};
int64_t MyAlarm::tiempo = 0L;
bool MyAlarm::running = false;
pour le rafraîchir, j'utilise setitimer:
int main(){
struct sigaction sa;
struct itimerval timer;
MyAlarm::run();
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &MyAlarm::callback;
sigaction (SIGALRM, &sa, NULL);
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 10000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 10000;
setitimer (ITIMER_REAL, &timer, NULL);
.....
Regardez setitimer et les variables ITIMER_VIRTUAL et ITIMER_REAL.
N'utilisez pas les fonctions alarm ou ualarm, vous aurez une faible précision lorsque vos processus auront du travail.
Cela devrait fonctionner ... testé sur un mac ...
#include <stdio.h>
#include <sys/time.h>
int main() {
struct timeval tv;
struct timezone tz;
struct tm *tm;
gettimeofday(&tv,&tz);
tm=localtime(&tv.tv_sec);
printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}
Ouais ... lancez-le deux fois et soustrayez ...
J'aime la méthode Hola Soy qui consiste à ne pas utiliser gettimeofday (). Il m'est arrivé sur un serveur en cours d'exécution, l'administrateur a modifié le fuseau horaire. L'horloge a été mise à jour pour afficher la même valeur locale (correcte). La fonction time () et gettimeofday () changeaient donc de 2 heures et tous les horodatages de certains services étaient bloqués.
En guise de mise à jour, il apparaît que windows clock () mesure l'heure de l'horloge murale (avec la précision CLOCKS_PER_SEC)
http://msdn.Microsoft.com/en-us/library/4e2ess30(VS.71).aspx
tandis que sur Linux, il mesure le temps processeur à travers les cœurs utilisés par les processus actuels
http://www.manpagez.com/man/3/clock
et (il semble, et comme indiqué par l'affiche originale) en réalité avec moins précision que CLOCKS_PER_SEC, bien que cela dépend peut-être de la version spécifique de Linux.
Je préfère la bibliothèque Boost Timer pour sa simplicité, mais si vous ne voulez pas utiliser les bibliothèques de troisième copie, utiliser clock () semble raisonnable.
J'ai écrit une classe C++
En utilisant timeb
.
#include <sys/timeb.h>
class msTimer
{
public:
msTimer();
void restart();
float elapsedMs();
private:
timeb t_start;
};
Fonctions membres:
msTimer::msTimer()
{
restart();
}
void msTimer::restart()
{
ftime(&t_start);
}
float msTimer::elapsedMs()
{
timeb t_now;
ftime(&t_now);
return (float)(t_now.time - t_start.time) * 1000.0f +
(float)(t_now.millitm - t_start.millitm);
}
Exemple d'utilisation:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
msTimer t;
for (int i = 0; i < 5000000; i++)
;
std::cout << t.elapsedMs() << endl;
return 0;
}
La sortie sur mon ordinateur est '19'. La précision de la classe msTimer
est de l'ordre de quelques millisecondes. Dans l'exemple d'utilisation ci-dessus, le temps total d'exécution pris par la boucle for
- est suivi. Cette fois-ci, le système d’exploitation a basculé dans le contexte d’exécution de main()
en raison du multitâche.