diff --git a/utils.hpp b/utils.hpp index 8ceccf7..5665a12 100644 --- a/utils.hpp +++ b/utils.hpp @@ -18,7 +18,7 @@ template auto max(const T & a, const T2 & b) -> decltyp template T sureAbs(const T & x) { return (x < T(0)) ? -x : x; } -//* +/* /// Generic operator<< for ostream, (to print std::vector, etd::list, std::map, etc). Can generate conflicts with specialized operator<< overloads. template class C, class... Args> std::ostream& operator<<(std::ostream& os, const C& objs) @@ -39,54 +39,87 @@ std::ostream& operator<<(std::ostream& os, const C& objs) /// Convenience macro to create a Chronometer object that will measure the execution time of its scope. #define TIMER(str) Chronometer __chrono((str)) +/// Convenience macro to create a Chronometer object that will measure the execution time of its scope, with a for-loop enveloping the code to time. +/// +/// Usage : TIMER_FOR("My timer", N, /* The code will be executed N times ! */) +#define TIMER_FOR(str, N, code) {Chronometer __chrono((str)); for(size_t i_TIMER_FOR = 0 ; i_TIMER_FOR < N ; i_TIMER_FOR++) {code} } + /// \class Chronometer class. Used to measure the execution time of its scope. /// /// Usage : -/// -/// { -/// TIMER("My timer"); -/// /* some code to be profiled */ -/// }// <--- the chronometer measures the time between the call to its constructor and the call to its destructor. +/// \code{.cpp} +/// { +/// TIMER("My timer"); +/// /* some code to be profiled */ +/// }// <--- the chronometer measures the time between the call to its constructor and the call to its destructor. +/// \endcode /// /// Possible output : /// /// My timer : 0.12317568 s (+/- 1e-09 s) /// +/// Alternate usage : +/// \code{.cpp} +/// { +/// Chronometer chronom("", false); +/// /* some code to time */ +/// chronom.MeasureTimeElapsed();// prints how much time elapsed since the creation of the object +/// /* some code to time */ +/// chronom.MeasureTimeElapsed();// prints how much time elapsed since the creation of the object +/// chronom.Reset();// resets the timer to 0 +/// /* some code to time */ +/// chronom.MeasureTimeElapsed();// prints how much time elapsed since the last reset +/// } // no message is displayed because displayAtDestruction_ is set to false +/// \endcode +/// template struct Chronometer { std::string name; std::chrono::high_resolution_clock::time_point t0; + bool displayAtDestruction; /// Creates the Chronometer object with the provided name and stores the time. - Chronometer(const std::string & name_ = "") + /// + /// \param name_ : Name to display + /// \param displayAtDestruction_ : if true, a message is printed to the console during the destruction of the object. + Chronometer(const std::string & name_ = "", bool displayAtDestruction_ = true) : name(name_), - t0(std::chrono::high_resolution_clock::now()) + t0(std::chrono::high_resolution_clock::now()), + displayAtDestruction(displayAtDestruction_) {} /// Measures the time elapsed between the creation of the object and its destruction, and prints the result in std::cout. - ~Chronometer() { MeasureTimeElapsed(); } + ~Chronometer() { if(displayAtDestruction) { MeasureTimeElapsed(); } } /// Resets the timer. Allows the measurement of the execution time of several sub-intervals in the current scope. void Reset() { t0 = std::chrono::high_resolution_clock::now(); } - /// Measures the time elapsed between the creation of the object and its destruction, and prints the result in std::cout. - void MeasureTimeElapsed() + double GetTime() const { - // measure time since object creation std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); std::chrono::duration time_span = std::chrono::duration_cast>(t1 - t0); - // clock resolution - auto resolution_ratio = std::chrono::high_resolution_clock::period(); - double resolution = double(resolution_ratio.num)/resolution_ratio.den; + return time_span.count(); + } + double GetResolution() const + { + auto resolution_ratio = std::chrono::high_resolution_clock::period(); + return double(resolution_ratio.num)/resolution_ratio.den; + } + + /// Measures the time elapsed between the creation of the object and its destruction, and prints the result in std::cout. + void MeasureTimeElapsed() const + { + // measure time since object creation and print it in the console std::cout.precision(16); - std::cout << name.c_str() << "\t: " << time_span.count() << " s (+/- " << resolution << " s)" << std::endl;// use of c_str() so that there is no ambiguity with the generic operator<< + std::cout << name.c_str() << "\t: " << GetTime() << " s (+/- " << GetResolution() << " s)" << std::endl;// use of c_str() so that there is no ambiguity with the generic operator<< } }; #else// chronometer #define TIMER(str) + #define TIMER_FOR(str, N, code) { for(size_t i_TIMER_FOR = 0 ; i_TIMER_FOR < N ; i_TIMER_FOR++) {code} } #endif// chronometer #endif