Comment utiliser clock () en C ++


127

Comment dois - je appeler clock()à C++?

Par exemple, je souhaite tester le temps nécessaire à une recherche linéaire pour trouver un élément donné dans un tableau.


1
Notez que l'heure de l'horloge murale n'est pas toujours un bon moyen de chronométrer les microbenchmarks. Pour obtenir des résultats cohérents, vous devez travailler autour de la mise à l'échelle de la fréquence du processeur (y compris le turbo Intel ou l'équivalent AMD, qui permet à votre horloge de processeur plus élevée lorsque les limites thermiques / de puissance le permettent). Le profilage avec des compteurs de performance peut vous donner des mesures dans les cycles d'horloge de cœur (et également des détails sur le fait qu'un goulot d'étranglement est un échec de cache par rapport au débit d'instructions vs la latence, en regardant des compteurs autres que de simples cycles). Sur Linux,perf stat -d ./a.out
Peter Cordes

Réponses:


207
#include <iostream>
#include <cstdio>
#include <ctime>

int main() {
    std::clock_t start;
    double duration;

    start = std::clock();

    /* Your algorithm here */

    duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;

    std::cout<<"printf: "<< duration <<'\n';
}

5
D'après ce que je peux voir ici cplusplus.com/reference/ctime/clock , vous n'avez pas besoin d'utiliser la notation "std ::". Utilisez simplement "clock ()"
gromit190

4
@Birger: Dans tous les projets sur lesquels j'ai travaillé, le style de code nécessite std :: avant chaque appel à std ::.
Th. Thielemann

2
Cela renvoie-t-il la réponse en quelques secondes?
Arnav Borborah

1
@ArnavBorborah Oui, c'est le cas.
QuantumHoneybees

1
@ Th.Thielemann à la fois clock()et clock_tsont de l' en- tête de C standard Library of time.h, et donc ne nécessitent pas l'utilisation de stdpréfixes d'espace de noms après l'inclusion de leurs bibliothèques. <ctime>encapsule cette valeur et cette fonction avec l' stdespace de noms, mais son utilisation n'est pas obligatoire. Vérifiez ici pour les détails de mise en œuvre: en.cppreference.com/w/cpp/header/ctime
kayleeFrye_onDeck

70

Une solution alternative, portable et plus précise, disponible depuis C ++ 11, consiste à utiliser std::chrono.

Voici un exemple:

#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    auto t1 = Clock::now();
    auto t2 = Clock::now();
    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()
              << " nanoseconds" << std::endl;
}

Lancer ceci sur ideone.com m'a donné:

Delta t2-t1: 282 nanoseconds

11
Si vous suggérez d'utiliser C ++ 11, vous pouvez tout aussi bien écrire using Clock=std::chrono::high_resolution_clock;. Voir l' alias de type .
JHBonarius

std::chrono::high_resolution_clockn'est pas monotone dans toutes les implémentations std lib. De la cppreference - En général, on devrait simplement utiliser std :: chrono :: regular_clock ou std :: chrono :: system_clock directement au lieu de std :: chrono :: high_resolution_clock: utilisez stabil_clock pour les mesures de durée et system_clock pour l'heure de l'horloge murale.
Kristianmitk le

30

clock()renvoie le nombre de coups d'horloge depuis le démarrage de votre programme. Il existe une constante associée CLOCKS_PER_SEC, qui vous indique le nombre de coups d'horloge en une seconde. Ainsi, vous pouvez tester n'importe quelle opération comme celle-ci:

clock_t startTime = clock();
doSomeOperation();
clock_t endTime = clock();
clock_t clockTicksTaken = endTime - startTime;
double timeInSeconds = clockTicksTaken / (double) CLOCKS_PER_SEC;

6
timeInSecondsvient toujours 0.000000pour moi. Comment le réparerais-je?
noufal

3
@noufal Peut-être que le temps passé est si court qu'il apparaît comme 0. Vous pouvez essayer d'utiliser a long doublepour obtenir plus de précision.
Gerard

probablement votre résolution d'horloge n'est pas assez élevée, donc aucun temps ne s'est écoulé.
Marco Freudenberger

4

Sur Windows au moins, le seul mécanisme de mesure pratiquement précis est QueryPerformanceCounter (QPC). std :: chrono est implémenté en l'utilisant (depuis VS2015, si vous l'utilisez), mais il n'est pas aussi précis que l'utilisation directe de QueryPerformanceCounter. En particulier, il est prétendu que le rapport à une granularité de 1 nanoseconde n'est absolument pas correct. Donc, si vous mesurez quelque chose qui prend très peu de temps (et votre cas pourrait bien être un tel cas), vous devriez utiliser QPC, ou l'équivalent pour votre système d'exploitation. Je me suis heurté à cela lors de la mesure des latences de cache, et j'ai noté quelques notes que vous pourriez trouver utiles, ici; https://github.com/jarlostensen/notesandcomments/blob/master/stdchronovsqcp.md


0
#include <iostream>
#include <ctime>
#include <cstdlib> //_sleep()  --- just a function that waits a certain amount of milliseconds

using namespace std;

int main()
{

    clock_t cl;     //initializing a clock type

    cl = clock();   //starting time of clock

    _sleep(5167);   //insert code here

    cl = clock() - cl;  //end point of clock

    _sleep(1000);   //testing to see if it actually stops at the end point

    cout << cl/(double)CLOCKS_PER_SEC << endl;  //prints the determined ticks per second (seconds passed)


    return 0;
}

//outputs "5.17"

Cela n'ajoute rien à la question déjà répondue. Sleep après cl = clock () - cl n'est pas nécessaire. Et le cout imprime les secondes et non les ticks par seconde. cl stocke les tics d'horloge.
Dr Yunke

0

Vous pourriez probablement être intéressé par une minuterie comme celle-ci: H: M: S. Msec.

le code sous Linux OS:

#include <iostream>
#include <unistd.h>

using namespace std;
void newline(); 

int main() {

int msec = 0;
int sec = 0;
int min = 0;
int hr = 0;


//cout << "Press any key to start:";
//char start = _gtech();

for (;;)
{
        newline();
                if(msec == 1000)
                {
                        ++sec;
                        msec = 0;
                }
                if(sec == 60)
                {
                        ++min;
                        sec = 0; 
                }
                if(min == 60)
                {
                        ++hr;
                        min = 0;
                }
        cout << hr << " : " << min << " : " << sec << " . " << msec << endl;
        ++msec;
        usleep(100000); 

}

    return 0;
}

void newline()
{
        cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}

Vous voudrez peut-être vérifier la première condition ... 10 msec = 1 sec?
Dr Yunke

2
Cela accumulera une erreur relative dans le temps car vous n'incluez pas le temps nécessaire à l'impression et usleepne reviendra pas toujours après exactement le montant que vous demandez. Parfois, ce sera plus long. Vous devez vérifier l'heure actuelle au début, puis vérifier l'heure actuelle et soustraire pour obtenir l'heure absolue depuis que vous avez commencé à chaque fois dans la boucle.
Peter Cordes

0

vous pouvez mesurer la durée de fonctionnement de votre programme. Les fonctions suivantes permettent de mesurer le temps CPU depuis le démarrage du programme:

  • Horloge C ++ (double) () / HORLOGES PAR SEC avec ctime inclus.
  • python time.clock () renvoie une valeur à virgule flottante en secondes.
  • Java System.nanoTime () renvoie une valeur longue en nanosecondes.

ma référence : Algorithms toolbox semaine 1 cours faisant partie de la spécialisation des structures de données et des algorithmes par l'Université de Californie à San Diego et la National Research University Higher School of Economics

afin que vous puissiez ajouter cette ligne de code après votre algorithme

cout << (double)clock() / CLOCKS_PER_SEC ;

Sortie attendue: la sortie représentant le nombre de clock ticks per second


1
La question est de se poser uniquement pour c ++. C'est donc bien que vous vous référiez à d'autres langages / scripts de programmation, mais c'est hors sujet.
dboy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.