J'essaie d'utiliser time () pour mesurer divers points de mon programme.
Ce que je ne comprends pas, c'est pourquoi les valeurs de l'avant et de l'après sont les mêmes? Je comprends que ce n'est pas la meilleure façon de présenter mon programme, je veux juste voir combien de temps quelque chose prend.
printf("**MyProgram::before time= %ld\n", time(NULL));
doSomthing();
doSomthingLong();
printf("**MyProgram::after time= %ld\n", time(NULL));
J'ai essayé:
struct timeval diff, startTV, endTV;
gettimeofday(&startTV, NULL);
doSomething();
doSomethingLong();
gettimeofday(&endTV, NULL);
timersub(&endTV, &startTV, &diff);
printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);
Comment lire un résultat de **time taken = 0 26339
? Cela signifie-t-il 26 339 nanosecondes = 26,3 ms?
Et **time taken = 4 45025
cela signifie-t-il 4 secondes et 25 ms?
time()
renvoie donc une valeur différente.time(NULL)
... la deuxième fois que vous appelez, ce sera N secondes après la première et donc ... différent (à moins que ce que vous faites ne le fasse pas) t prendre une seconde pour terminer ... dans ce cas, ce sera le même que le premier).Réponses:
la source
#include <chrono>
directive et je changerais le temps de rapports que:std::cout << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) /1000000.0 <<std::endl;
(et ne pas oublier le C ++ 11 drapeau lors de la compilation:-std=c++11
)La
time()
fonction n'est précise qu'à une seconde près, mais il y a desCLOCKS_PER_SEC
"horloges" à l'intérieur d'une seconde. Il s'agit d'une mesure facile et portable, même si elle est trop simplifiée.la source
clock()
mesure le temps CPU, et non le temps réel écoulé (qui peut être beaucoup plus long).Vous pouvez faire abstraction du mécanisme de mesure du temps et faire mesurer le temps d'exécution de chaque appelable avec un code supplémentaire minimal , simplement en étant appelé via une structure de minuterie. De plus, au moment de la compilation, vous pouvez paramétrer le type de synchronisation (millisecondes, nanosecondes, etc.).
Merci à l'examen de Loki Astari et à la suggestion d'utiliser des modèles variadiques. C'est pourquoi l'appel de fonction renvoyé.
Demo
Selon le commentaire de Howard Hinnant, il est préférable de ne pas s'échapper du système de chrono jusqu'à ce que nous le devions. Ainsi, la classe ci-dessus pourrait donner à l'utilisateur le choix d'appeler
count
manuellement en fournissant une méthode statique supplémentaire (affichée en C ++ 14)et être le plus utile pour les clients qui
Le code complet peut être trouvé ici . Ma tentative de construire un outil d'analyse comparative basé sur le chrono est enregistrée ici .
Si C ++ 17
std::invoke
est disponible, l'appel de l'appelableexecution
pourrait se faire comme ceci:pour fournir des callables qui sont des pointeurs vers des fonctions membres.
la source
code_timer
) qui prend l'heure de début (std::chrono::system_clock::now();
) dans le constructeur, une méthodecode_timer::ellapsed
qui mesure la différence entre un nouvelnow()
appel et celui du constructeur et unecode_timer::reset
méthode qui réinitialise l'heure de début à un nouveaunow()
résultat. Pour mesurer l'exécution d'un foncteur dans mon code, j'utilise une fonction libre, en dehors de la classe. Cela permet de mesurer le temps entre la construction d'un objet et la fin d'un appel asynchrone.chrono
système jusqu'à ce que vous deviez (éviter d'utiliser.count()
). Laissez le client appeler.count()
lorsqu'il est forcé de le faire (par exemple pour les E / S, ce qui est en effet malheureux). Le client peut vouloir post-traiter un tas de durées avant les E / S (par exemple la moyenne) et cela est mieux fait dans lechrono
système.std::forward<F>(func)
?std::forward<decltype(func)>(func)
parce qu'il peut s'appliquer aux arguments de lambdas (auto&& func
) génériques où ilF
n'y a pas de syntaxe et il est facile de résumer dans une macro utilitaire#define fw(arg) std::forward<decltype(arg)>(arg)
que je fais dans ma bibliothèque de référence (c'est donc un reste syntaxique sur lequel je n'élabore pas beaucoup dans la réponse)Comme je peux le voir dans votre question, il semble que vous souhaitiez connaître le temps écoulé après l'exécution d'un morceau de code. Je suppose que vous seriez à l'aise de voir les résultats en secondes. Si c'est le cas, essayez d'utiliser la
difftime()
fonction comme indiqué ci-dessous. J'espère que ceci résoudra votre problème.la source
Windows uniquement: (La balise Linux a été ajoutée après avoir posté cette réponse)
Vous pouvez utiliser GetTickCount () pour obtenir le nombre de millisecondes qui se sont écoulées depuis le démarrage du système.
la source
SleepEx(5000,0)
à la place de // Effectuer une opération longue et différente deafter
etbefore
était presque 5 secondes.time(NULL)
renvoie le nombre de secondes écoulées depuis le 01/01/1970 à 00:00 ( l'Epoch ). La différence entre les deux valeurs est donc le nombre de secondes que votre traitement a pris.Vous pouvez obtenir des résultats plus fins avec
getttimeofday()
, qui renvoient l'heure actuelle en secondes, tout commetime()
en microsecondes.la source
la fonction time (NULL) renverra le nombre de secondes écoulées depuis le 01/01/1970 à 00:00. Et parce que, cette fonction est appelée à différents moments de votre programme, ce sera toujours différent en C ++
la source
L'utilisation est ci-dessous ::
Ceci est similaire au RAII dans sa portée
NOTE ce n'est pas le mien, mais je pensais que c'était pertinent ici
la source
la source
Les valeurs imprimées par votre deuxième programme sont les secondes et les microsecondes.
la source
la source
C ++ std :: chrono a clairement l'avantage d'être multiplateforme. Cependant, il introduit également une surcharge importante par rapport à POSIX clock_gettime (). Sur ma boîte Linux, toutes les
std::chrono::xxx_clock::now()
saveurs fonctionnent à peu près de la même manière:Bien que Posix
clock_gettime(CLOCK_MONOTONIC, &time)
devrait être identique ,steady_clock::now()
mais il est plus que temps de x3 plus vite!Voici mon test, pour être complet.
Et voici la sortie que j'obtiens lors de la compilation avec gcc7.2 -O3:
la source
L'
time(NULL)
appel de fonction renverra le nombre de secondes écoulées depuis epoc: 1er janvier 1970. Peut-être que vous voulez faire la différence entre deux horodatages:la source
Comme d'autres l'ont déjà noté, la fonction time () dans la bibliothèque standard C n'a pas une résolution meilleure qu'une seconde. La seule fonction C entièrement portable qui peut fournir une meilleure résolution semble être clock (), mais qui mesure le temps processeur plutôt que le temps d'horloge murale. Si l'on se contente de se limiter aux plateformes POSIX (par exemple Linux), la fonction clock_gettime () est un bon choix.
Depuis C ++ 11, il existe de bien meilleures fonctionnalités de synchronisation disponibles qui offrent une meilleure résolution sous une forme qui devrait être très portable sur différents compilateurs et systèmes d'exploitation. De même, la bibliothèque boost :: datetime fournit de bonnes classes de synchronisation à haute résolution qui devraient être hautement portables.
Un défi dans l'utilisation de l'une de ces fonctionnalités est le délai introduit par l'interrogation de l'horloge système. De l'expérimentation de clock_gettime (), boost :: datetime et std :: chrono, ce délai peut facilement être une question de microsecondes. Ainsi, lorsque vous mesurez la durée d'une partie de votre code, vous devez autoriser une erreur de mesure d'environ cette taille, ou essayer de corriger cette erreur nulle d'une manière ou d'une autre. Idéalement, vous souhaiterez peut-être rassembler plusieurs mesures du temps pris par votre fonction et calculer le temps moyen ou maximum / minimum pris sur de nombreuses exécutions.
Pour aider avec tous ces problèmes de portabilité et de collecte de statistiques, j'ai développé la bibliothèque cxx-rtimers disponible sur Github qui essaie de fournir une API simple pour chronométrer des blocs de code C ++, calculer zéro erreur et rapporter les statistiques de plusieurs temporisateurs intégrés dans votre code. Si vous avez un compilateur C ++ 11, vous
#include <rtimers/cxx11.hpp>
utilisez simplement quelque chose comme:À la sortie du programme, vous obtiendrez un résumé des statistiques de synchronisation écrites dans std :: cerr, telles que:
qui montre le temps moyen, son écart-type, les limites supérieure et inférieure et le nombre de fois que cette fonction a été appelée.
Si vous souhaitez utiliser des fonctions de synchronisation spécifiques à Linux, vous pouvez
#include <rtimers/posix.hpp>
, ou si vous avez les bibliothèques Boost mais un ancien compilateur C ++, vous pouvez#include <rtimers/boost.hpp>
. Il existe également des versions de ces classes de temporisation qui peuvent collecter des informations de synchronisation statistiques sur plusieurs threads. Il existe également des méthodes qui vous permettent d'estimer l'erreur zéro associée à deux requêtes immédiatement consécutives de l'horloge système.la source
En interne, la fonction accède à l'horloge du système, c'est pourquoi elle renvoie des valeurs différentes à chaque appel. En général, avec les langages non fonctionnels, il peut y avoir de nombreux effets secondaires et un état caché dans les fonctions que vous ne pouvez pas voir simplement en regardant le nom et les arguments de la fonction.
la source
D'après ce que l'on voit, tv_sec stocke les secondes écoulées tandis que tv_usec stockait les microsecondes écoulées séparément. Et ce ne sont pas les conversions les uns des autres. Par conséquent, ils doivent être changés en unité appropriée et ajoutés pour obtenir le temps total écoulé.
la source
Sous linux, clock_gettime () est l'un des bons choix. Vous devez lier la bibliothèque en temps réel (-lrt).
la source
J'avais besoin de mesurer le temps d'exécution de fonctions individuelles au sein d'une bibliothèque. Je ne voulais pas avoir à encapsuler chaque appel de chaque fonction avec une fonction de mesure du temps car c'est laid et approfondit la pile d'appels. Je ne voulais pas non plus mettre le code de la minuterie en haut et en bas de chaque fonction car cela gâche quand la fonction peut quitter tôt ou lever des exceptions par exemple. Donc, ce que j'ai fini par faire, c'était de créer une minuterie qui utilise sa propre durée de vie pour mesurer le temps.
De cette façon, je peux mesurer le temps passé par un bloc de code en instanciant simplement l'un de ces objets au début du bloc de code en question (fonction ou toute étendue vraiment), puis en permettant au destructeur d'instances de mesurer le temps écoulé depuis construction lorsque l'instance sort du champ d'application. Vous pouvez trouver l'exemple complet ici mais la structure est extrêmement simple:
La structure vous rappellera sur le foncteur fourni lorsqu'il sortira du champ d'application afin que vous puissiez faire quelque chose avec les informations de synchronisation (les imprimer ou les stocker ou autre). Si vous avez besoin de faire quelque chose d'encore plus complexe, vous pouvez même utiliser
std::bind
avecstd::placeholders
pour rappeler des fonctions avec plus d'arguments.Voici un exemple rapide de son utilisation:
Si vous voulez être plus délibéré, vous pouvez également utiliser
new
etdelete
pour démarrer et arrêter explicitement le minuteur sans compter sur la portée pour le faire pour vous.la source
Ce sont les mêmes parce que votre fonction doSomething se produit plus rapidement que la granularité de la minuterie. Essayer:
la source
La raison pour laquelle les deux valeurs sont identiques est que votre longue procédure ne prend pas autant de temps - moins d'une seconde. Vous pouvez essayer d'ajouter simplement une longue boucle (pour (int i = 0; i <100000000; i ++);) à la fin de la fonction pour vous assurer que c'est bien le problème, alors nous pouvons y aller ...
Si ce qui précède s'avère vrai, vous devrez trouver une fonction système différente (je comprends que vous travaillez sur Linux, donc je ne peux pas vous aider avec le nom de la fonction) pour mesurer le temps plus précisément. Je suis sûr qu'il existe une fonction similaire à GetTickCount () sous Linux, il vous suffit de la trouver.
la source
J'utilise généralement les éléments suivants:
C'est la même chose que @ nikos-athanasiou a proposé, sauf que j'évite d'utiliser une horloge non stable et utilise un nombre flottant de secondes comme durée.
la source
high_resolution_clock
est typiquement un typedef pour soitsystem_clock
ousteady_clock
. Donc, pour tracer questd::conditional
si lais_steady
partie est vraie, vous choisissez alorshigh_resolution_clock
qui est (un typedef)steady_clock
. Si c'est faux, vous choisissez àsteady_clock
nouveau. Utilisez justesteady_clock
depuis le début ...high_resolution_clock may be a synonym for system_clock or steady_clock
. La raison en est la suivante:high_resolution_clock
représente les horloges avec la période de tick la plus courte, donc quelle que soit la mise en œuvre, elle a deux choix, stable ou non. Quel que soit le choix que nous faisons, dire que l'implémentation sera différente des deux autres horloges revient à dire que nous avons une meilleure implémentation pour une horloge stable (ou non) que nous choisissons de ne pas utiliser (pour des horloges stables ou non). Savoir comment est bon, savoir pourquoi est meilleurEn réponse aux trois questions spécifiques d' OP .
"Ce que je ne comprends pas, c'est pourquoi les valeurs d'avant et d'après sont les mêmes? "
La première question et l'exemple de code montre que
time()
la résolution est de 1 seconde, la réponse doit donc être que les deux fonctions s'exécutent en moins de 1 seconde. Mais parfois, il informera (apparemment de manière illogique) 1 seconde si les deux marques de minuterie chevauchent une limite d'une seconde.L'exemple suivant utilise
gettimeofday()
qui remplit cette structureet la deuxième question demande: "Comment lire un résultat
**time taken = 0 26339
? Cela signifie-t-il 26 339 nanosecondes = 26,3 ms?"Ma deuxième réponse est que le temps pris est de 0 seconde et 26339 microsecondes, soit 0,026339 seconde, ce qui confirme le premier exemple s'exécutant en moins de 1 seconde.
La troisième question demande: "Qu'en est-il
**time taken = 4 45025
, cela signifie-t-il 4 secondes et 25 ms?"Ma troisième réponse est que le temps nécessaire est de 4 secondes et 45025 microsecondes, soit 4,045025 secondes, ce qui montre que OP a modifié les tâches effectuées par les deux fonctions qu'il avait précédemment chronométrées.
la source
Exemple similaire à celui disponible ici, uniquement avec une fonction de conversion supplémentaire + impression.
la source
J'ai créé une classe pour mesurer automatiquement le temps écoulé, veuillez vérifier le code (c ++ 11) dans ce lien: https://github.com/sonnt174/Common/blob/master/time_measure.h
Exemple d'utilisation de la classe TimeMeasure:
la source
Matlab
parfumé!tic
démarre un chronomètre pour mesurer les performances. La fonction enregistre l'heure interne à l'exécution de la commande tic. Affichez le temps écoulé avec latoc
fonction.la source
Vous pouvez utiliser la bibliothèque SFML , qui est une bibliothèque multimédia simple et rapide. Il comprend de nombreuses classes utiles et bien définies comme l'horloge, la prise, le son, les graphiques, etc. Il est si facile à utiliser et hautement recommandé.
Ceci est un exemple pour cette question.
la source