1 // Copyright (c) 2017-2021, Lawrence Livermore National Security, LLC and 2 // other Axom Project Developers. See the top-level LICENSE file for details. 3 // 4 // SPDX-License-Identifier: (BSD-3-Clause) 5 6 /*! 7 ****************************************************************************** 8 * \file Timer.hpp 9 * 10 * \brief Defines a simple Timer class to measure execution time. 11 * 12 ****************************************************************************** 13 */ 14 15 #ifndef TIMER_HPP_ 16 #define TIMER_HPP_ 17 18 #include "axom/config.hpp" 19 20 #include <chrono> 21 22 namespace axom 23 { 24 namespace utilities 25 { 26 /*! 27 * \brief A simple Timer class to measure execution time. 28 * 29 * \note We might want to extend the functionality of the timer class 30 * by making HighPrecisionTimer a template parameter. 31 * API requirements for HighPrecisionTimer class 32 * -- must be default constructible 33 * -- timing functions: 34 * void start() 35 * void stop() 36 * void reset() 37 * -- elapsed time functions: 38 * double elapsedTimeInSec() 39 * double elapsedTimeInMilliSec() 40 * double elapsedTimeInMicroSec() 41 * 42 * \note We might want to add support for pausing and resuming the timer while 43 * accumulating the time differences 44 * 45 * Example Usage: 46 * \code 47 * 48 * utilities::Timer t; 49 * t.start(); 50 * 51 * // code to measure its execution time 52 * 53 * t.stop(); 54 * std::cout << "Elapsed Time: << t.elapsed() << std::endl; 55 * 56 * t.reset(); 57 * 58 * \endcode 59 */ 60 class Timer 61 { 62 private: 63 using ClockType = std::chrono::high_resolution_clock; 64 using TimeStruct = std::chrono::time_point<ClockType>; 65 using TimeDiff = std::chrono::duration<double>; 66 using MilliTimeDiff = std::chrono::duration<double, std::milli>; 67 using MicroTimeDiff = std::chrono::duration<double, std::micro>; 68 69 public: 70 /*! 71 * \brief Default constructor. 72 * \param startRunning Indicates whether to start the timer 73 * during construction (default is false) 74 */ Timer(bool startRunning=false)75 Timer(bool startRunning = false) : m_running(startRunning) 76 { 77 if(m_running) start(); 78 } 79 80 /*! 81 * \brief Starts the timer.Sets the start time of this Timer instance. 82 */ start()83 void start() 84 { 85 m_running = true; 86 m_startTime = ClockType::now(); 87 } 88 89 /*! 90 * \brief Stops the timer. Sets the end time of this Timer instance. 91 */ stop()92 void stop() 93 { 94 m_stopTime = ClockType::now(); 95 m_running = false; 96 } 97 98 /*! 99 * \brief Returns the elapsed time in seconds. 100 * \return t the elapsed time in seconds. 101 */ elapsed()102 double elapsed() { return elapsedTimeInSec(); }; 103 104 /*! 105 * \brief Returns the elapsed time in seconds. 106 * \return t the elapsed time in seconds. 107 */ elapsedTimeInSec()108 double elapsedTimeInSec() 109 { 110 if(m_running) stop(); 111 return clockDiff().count(); 112 } 113 114 /*! 115 * \brief Returns the elapsed time in milliseconds. 116 * \return t the elapsed time in milliseconds. 117 */ elapsedTimeInMilliSec()118 double elapsedTimeInMilliSec() 119 { 120 if(m_running) stop(); 121 return std::chrono::duration_cast<MilliTimeDiff>(clockDiff()).count(); 122 } 123 124 /*! 125 * \brief Returns the elapsed time in microseconds. 126 * \return t the elapsed time in microseconds. 127 */ elapsedTimeInMicroSec()128 double elapsedTimeInMicroSec() 129 { 130 if(m_running) stop(); 131 return std::chrono::duration_cast<MicroTimeDiff>(clockDiff()).count(); 132 } 133 134 /*! 135 * \brief Resets the timer. 136 * \post this->elapsed()==0.0 137 */ reset()138 void reset() 139 { 140 m_running = false; 141 m_startTime = m_stopTime = TimeStruct(); 142 } 143 144 private: 145 /*! \brief Computes the difference between start() and stop() */ clockDiff() const146 TimeDiff clockDiff() const { return m_stopTime - m_startTime; } 147 148 TimeStruct m_startTime; 149 TimeStruct m_stopTime; 150 bool m_running; 151 }; 152 153 } // namespace utilities 154 } // namespace axom 155 156 #endif // TIMER_HPP_ 157