Comment calculer un décalage horaire en C ++

95

Quelle est la meilleure façon de calculer un décalage horaire en C ++? Je chronomètre la vitesse d'exécution d'un programme, donc je m'intéresse aux millisecondes. Mieux encore, secondes. Millisecondes.

La réponse acceptée fonctionne, mais doit inclure ctime ou time.h comme indiqué dans les commentaires.

Jack BeNimble
la source
Dupe, mais ne peut pas lier maintenant
Robert Gould
2
Le vote pour clôturer était trop peu, trop tard. J'ai une réponse fonctionnelle. Bien essayé quand même. Btw, je n'ai pas trouvé de lien non plus.
Jack BeNimble
C'est pour les fenêtres? puis essayez GetTickCount (API Windows)
aJ.
5
Robert: Heureusement, car la nouvelle publication a permis plusieurs réponses supplémentaires, dont une que j'ai sélectionnée. Sérieusement, je remets en question la valeur de la fermeture d'un post dup. Et si certaines solutions n'étaient pas mentionnées dans la première? De nouvelles technologies développées? Vous ne le trouvez pas à cause de rubriques différentes?
Jack BeNimble
2
@JackBeNimble ayant été le destinataire de quelques "dups" qui n'étaient pas exactement des dups (peut-être des gens qui lisent peut-être rapidement la question et la marquent parce que cela ressemble à une autre question), je suis tout à fait d'accord avec votre point ... probablement un point pour l'échange de meta stack: o
code_fodder

Réponses:

123

Voir la std::clock()fonction.

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

Si vous voulez calculer le temps d'exécution pour vous-même (pas pour l'utilisateur), il est préférable de le faire en ticks d'horloge (pas en secondes).

EDIT:
fichiers d'en-tête responsables - <ctime>ou<time.h>

bayda
la source
4
Gardez à l'esprit que même si clock () renvoie un certain nombre de millisecondes, la précision de clock () peut être bien pire que cela. Dans Windows, la précision de la fonction clock () est de l'ordre de 40 ms.
John Dibling
2
J'ai essayé ceci sur Mac 10.7. mon application exécute un fichier de 100 Mo en 15 secondes, mais le temps de différence rapporte 61 secondes. Pas beaucoup d'utilité. Je pense que le temps () est probablement meilleur.
Miek le
5
clock()renvoie le temps CPU consommé par le programme. Donc, si le programme est exécuté en parallèle, le temps retourné par la fonction serait le temps accumulé sur tous les processeurs, plutôt que le temps écoulé cplusplus.com/reference/ctime/clock
Ameer Jewdaki
3
Cette réponse est trompeuse car elle indique le temps CPU, pas l'heure réelle de l'horloge murale.
Ultraviolet
1
Je suis d'accord avec Ultraviolet ici, utiliser le temps CPU pour mesurer la vitesse d'un programme semble être la mauvaise chose à faire. OP devrait décocher ceci comme la bonne réponse. OMI, vous devriez utiliser std :: chrono :: stabil_clock :: now () comme décrit par plusieurs réponses dans le fil suivant stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun
37

si vous utilisez c ++ 11, voici un simple wrapper (voir l' essentiel ):

#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_;
};

Ou pour c ++ 03 sur * 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_;
};

Exemple d'utilisation:

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
la source
2
Une autre option serait d'utiliser boost :: chrono au lieu de l'espace de noms C ++ 11 STL std :: chrono. Merci pour votre code.
Didac Perez Parera
Attention: cela ne fonctionnera pas si l'utilisateur change son temps entre Timer()et l'appel à elapsed()if !std::chrono::high_resolution_clock::is_steady- ce qui est le cas sous Linux!
jhasse
30

J'envisagerais sérieusement l'utilisation de Boost, en particulier boost :: posix_time :: ptime et boost :: posix_time :: time_duration (à http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time .html ).

Il est multiplateforme, facile à utiliser et, d'après mon expérience, il offre le plus haut niveau de résolution temporelle qu'un système d'exploitation offre. Peut-être aussi très important; il fournit de très bons opérateurs IO.

Pour l'utiliser pour calculer la différence dans l'exécution du programme (en microsecondes; probablement exagéré), cela ressemblerait à quelque chose comme ceci [navigateur écrit, non testé]:

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
la source
3
Mais boost local_time () n'est pas monotone et ne doit donc pas être utilisé pour mesurer les intervalles de temps. Je n'ai pas trouvé de moyen d'accéder à l'heure monotone depuis Boost.
gatopeich
27

J'ai ajouté cette réponse pour préciser que la réponse acceptée montre le temps CPU qui n'est peut-être pas le temps souhaité. Parce que selon la référence , il y a le temps CPU et l'heure de l'horloge murale . L'heure de l'horloge murale est l'heure qui montre le temps écoulé réel indépendamment de toutes les autres conditions telles que le processeur partagé par d'autres processus. Par exemple, j'ai utilisé plusieurs processeurs pour effectuer une certaine tâche et le temps processeur était élevé à 18 secondes, alors qu'il fallait en fait 2 secondes en temps réel de l'horloge murale.

Pour obtenir l'heure réelle que vous faites,

#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();
Ultra-violet
la source
2
Je n'aurais pas pu utiliser std :: chrono sans cette réponse, merci!
giles
13

boost 1.46.0 et plus inclut la bibliothèque Chrono :

La classe thread_clock donne accès à l'horloge murale réelle du thread, c'est-à-dire à l'horloge réelle du temps CPU du thread appelant. L'heure actuelle relative du thread peut être obtenue en appelant thread_clock :: now ()

#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
la source
7
De plus, C ++ 11 a un std::chronoespace de noms avec presque le même contenu.
ulidtko
12

Sous Windows: utilisez GetTickCount

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

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

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

}
un J.
la source
8

Vous pouvez également utiliser clock_gettime . Cette méthode peut être utilisée pour mesurer:

  1. Horloge en temps réel à l'échelle du système
  2. Horloge monotone à l'échelle du système
  3. Temps CPU par processus
  4. Temps CPU par processus Thread

Le code est le suivant:

#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
la source
6

juste au cas où vous seriez sous Unix, vous pouvez utiliser timepour obtenir le temps d'exécution:

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

Juste une remarque: si vous utilisez Windows et que vous avez vraiment besoin de précision, vous pouvez utiliser QueryPerformanceCounter . Cela vous donne du temps en (potentiellement) nanosecondes .

v3.
la source
5

Pour moi, le moyen le plus simple est:

#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();

en utilisant ce morceau de code, vous n'avez pas à faire le classique end - start .

Profitez de votre approche préférée.

user1823890
la source
est t.elapsed () en sec ou mili-sec?
mkuse
4

Obtenez l'heure système en millisecondes au début, puis à nouveau à la fin, et soustrayez.

Pour obtenir le nombre de millisecondes depuis 1970 dans POSIX, vous écrirez:

struct timeval tv;

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

Pour obtenir le nombre de millisecondes depuis 1601 sous Windows, vous écririez:

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);

Si vous vouliez normaliser la réponse Windows afin qu'elle renvoie également le nombre de millisecondes depuis 1970, vous devrez alors ajuster votre réponse de 11644473600000 millisecondes. Mais ce n'est pas nécessaire si vous vous souciez uniquement du temps écoulé.

Jared Oberhaus
la source
4

Si vous utilisez:

tstart = clock();

// ...do something...

tend = clock();

Ensuite, vous aurez besoin des éléments suivants pour obtenir le temps en secondes:

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

Cela semble fonctionner correctement pour Intel Mac 10.7:

#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
la source