Comment obtenir la durée, sous forme d'int milli et de secondes flottantes à partir de <chrono>?

93

J'essaie d'utiliser la bibliothèque chrono pour les minuteries et les durées.

Je veux pouvoir avoir un Duration frameStart;(depuis le début de l'application) et un Duration frameDelta;(temps entre les images)

J'ai besoin de pouvoir obtenir la frameDeltadurée en millisecondes et en flottant secondes.

Comment faites-vous cela avec les nouvelles <chrono>bibliothèques c ++ 11 ? J'ai travaillé dessus et j'ai cherché sur Google (les informations sont rares). Le code est fortement basé sur des modèles et nécessite des castings et des choses spéciales, je ne peux pas comprendre comment utiliser cette bibliothèque correctement.

EddieV223
la source
Attribuez la durée à une durée avec un rapport secondes (ou millisecondes) puis appelez count-la ...
K-ballo
auto delta = durée_cast <secondes> (frameDelta) .count (); Comme ça? Il retourne longtemps pas un flotteur.
EddieV223
3
@ K-ballo, si la durée a une résolution plus élevée que le type auquel vous l'assignez, l'affectation sera mal formée, pour éviter de perdre en précision. Vous devez utiliser une durée avec une représentation en virgule flottante, ou utiliserduration_cast
Jonathan Wakely
@JonathanWakely: Oh, alors je l'ai mal utilisé! :(
K-ballo

Réponses:

151

Est-ce ce que vous recherchez?

#include <chrono>
#include <iostream>

int main()
{
    typedef std::chrono::high_resolution_clock Time;
    typedef std::chrono::milliseconds ms;
    typedef std::chrono::duration<float> fsec;
    auto t0 = Time::now();
    auto t1 = Time::now();
    fsec fs = t1 - t0;
    ms d = std::chrono::duration_cast<ms>(fs);
    std::cout << fs.count() << "s\n";
    std::cout << d.count() << "ms\n";
}

qui pour moi imprime:

6.5e-08s
0ms
Howard Hinnant
la source
2
pourquoi ne pas utiliser autosur fset d?
TemplateRex
26
@rhalbersma: L'utilisation de autoserait très bien d, car le résultat duration_cast<ms>est ms. Cependant, for fs autone serait pas approprié car le résultat de t1-t0a un type high_resolution_clock::durationqui n'est pas nécessairement du même type que duration<float>. Par exemple, sur mon système, c'est le cas duration<long long, nano>. Il y a donc une conversion implicite de la base intégrale à la base nanosecondsflottante qui se secondsproduit sur cette ligne, uniquement parce que le type de destination est spécifié avec fsec.
Howard Hinnant
2
Ce sont des informations utiles. Juste curieux: serait auto fs = std::chrono::duration_cast<fsec>(t1 - t0);exagéré pédant?
TemplateRex
@rhalbersma: Cela fonctionnerait tout aussi bien et ferait exactement la même chose. Quant à savoir lequel doit être préféré est entièrement stylistique en ce qui me concerne.
Howard Hinnant
2
sachez que dans certains scénarios du monde réel (le compilateur ms et les bibliothèques par exemple), le 'high_resolution_clock' manquera des temps de l'ordre de la microseconde et ce code crachera des zéros,
jheriko
19

Deviner ce que vous demandez. Je suppose qu'en millisecondes, vous recherchez quelque chose qui agit comme suit,

double mticks()
{
    struct timeval tv;
    gettimeofday(&tv, 0);
    return (double) tv.tv_usec / 1000 + tv.tv_sec * 1000;
}

mais utilise à la std::chronoplace,

double mticks()
{
    typedef std::chrono::high_resolution_clock clock;
    typedef std::chrono::duration<float, std::milli> duration;

    static clock::time_point start = clock::now();
    duration elapsed = clock::now() - start;
    return elapsed.count();
}

J'espère que cela t'aides.

Billy the kid
la source
Bienvenue dans Stack Overflow. Ce serait formidable si vous pouviez fournir des détails supplémentaires à votre code. Cela aiderait d'autres personnes à comprendre ce que vous essayez d'accomplir et comment vos solutions fonctionnent. Merci!
Luís Cruz
FYI - c'était l'exemple le plus clair et le plus utile des dizaines que j'ai examinés. Merci d'avoir rendu compréhensibles les fonctions chrono éternellement déroutantes.
SMGreenfield
15

Je ne sais pas ce que signifie "millisecondes et secondes flottantes", mais cela devrait vous donner une idée:

#include <chrono>
#include <thread>
#include <iostream>

int main()
{
  auto then = std::chrono::system_clock::now();
  std::this_thread::sleep_for(std::chrono::seconds(1));
  auto now = std::chrono::system_clock::now();
  auto dur = now - then;
  typedef std::chrono::duration<float> float_seconds;
  auto secs = std::chrono::duration_cast<float_seconds>(dur);
  std::cout << secs.count() << '\n';
}
Jonathan Wakely
la source
Je suppose qu'il veut le réel countcomme un float?
K-ballo
1
C'est ce qui est imprimé à la fin. Mais je ne savais pas s'il voulait des millisecondes comme un entier, ou des millisecondes après la seconde, ou quoi.
Jonathan Wakely
Je voudrais pouvoir obtenir à partir d'un chrono :: duration la durée représentée en millisecondes int, ou float secondes (fraction de seconde)
EddieV223
La réponse de Howard fait exactement cela
Jonathan Wakely
8

Dans le style AAA en utilisant l' idiome d'initialisation explicitement typé :

#include <chrono>
#include <iostream>

int main(){
  auto start = std::chrono::high_resolution_clock::now();
  // Code to time here...
  auto end = std::chrono::high_resolution_clock::now();

  auto dur = end - start;
  auto i_millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
  auto f_secs = std::chrono::duration_cast<std::chrono::duration<float>>(dur);
  std::cout << i_millis.count() << '\n';
  std::cout << f_secs.count() << '\n';
}
Chris Drew
la source