mardi 7 décembre 2010

C++0x - Chronomètres

Enfin, et c'est pas trop tôt, une interface C++ pour mesurer le temps. Celle-ci vient de plus avec d'intéressantes fonctionnalités. Mais voyons d'abord un petit programme d'exemple:


#include <chrono>
#include <iostream>

int main()
{
auto t1 = std::chrono::system_clock::now();
usleep(100000);
auto t2 = std::chrono::system_clock::now();

std::cout << (t2 - t1).count() << std::endl;

return 0;
}

Tout bête! Remarquez l'utilisation de auto pour ne pas avoir à m'ennuyer à définir le complexe type retourné par la méthode statique. Cependant, et c'est là que je trouve que le standard fait très fort, les types fournis permettent de s'affranchir totalement des problèmes d'unités souvent rencontrés dans ces cas là: quelle est la précision fournie par la bibliothèque? Et quelle est la précision voulue par l'utilisateur? C'est là que le type duration (ici implicite) de (t2 - t1) donne toute sa mesure. Regardons plutôt:

#include <chrono>
#include <iostream>

int main()
{
auto t1 = std::chrono::system_clock::now();
usleep(100000);
auto t2 = std::chrono::system_clock::now();

std::chrono::nanoseconds n = (t2 - t1);
std::cout << n.count() << std::endl;

std::chrono::microseconds u = (t2 - t1);
std::cout << u.count() << std::endl;

std::chrono::duration<double> d = (t2 - t1);
std::cout << d.count() << std::endl;

return 0;
}

Là où ça devient magique, c'est que la valeur est automatiquement convertie dans l'unité demandée. Le programme affiche:

100059000
100059
0.100059

Ces types std::chrono::nanoseconds et std::chrono::microseconds sont des typedef sur le type duration, lequel prend comme paramètres templates le type de base, et un ratio (avec un défaut de 1, pour les secondes).

Et, cerise sur le gâteau, g++ refusera même de compiler une conversion non exacte. La ligne
std::chrono::seconds s = (t2 - t1);
renvoie le message d'erreur suivant:
error: static assertion failed: "the resulting duration is not exactly representable"
En effet, le typedef std::seconds prenant en type de base un entier, la conversion perd en précision. Pour que cela marche, il faut utiliser un double, comme dans l'exemple précédent.

Qui a dit que le C++ n'était pas intuitif? :)

Aucun commentaire: