1 #ifndef _ScopedTimer_h_ 2 #define _ScopedTimer_h_ 3 4 #include <memory> 5 #include <string> 6 7 #include "Export.h" 8 9 #include <chrono> 10 11 12 //! Logs period during which this object existed. 13 //! 14 //! Created in the scope of a function, and passed the appropriate name, it will 15 //! output to DebugLogger() the time elapsed while the function was executing. 16 //! 17 //! If @p enable_output is true and duration is greater than threshold then 18 //! print output. 19 class FO_COMMON_API ScopedTimer { 20 public: 21 explicit ScopedTimer(const std::string& timed_name = "", bool enable_output = false, 22 std::chrono::microseconds threshold = std::chrono::milliseconds(1)); 23 ScopedTimer(const std::string& timed_name, std::chrono::microseconds threshold); 24 ~ScopedTimer(); 25 26 void restart(); 27 28 double duration() const; 29 std::string DurationString() const; 30 31 class Impl; 32 33 private: 34 std::unique_ptr<Impl> const m_impl; 35 }; 36 37 38 //! Logs period during which a this object or named sub sections existed. 39 //! 40 //! Similar to ScopedTimer SectionedScopedTimer times the duration of its own 41 //! existence. It also allows the creation of sub section timers. Timers are 42 //! created by calling EnterSection(). 43 //! 44 //! Only one sub-section timer is active at any time. 45 //! 46 //! Timers can be re-entered, which is effective to profile looping structures. 47 //! 48 //! Any name is valid except an empty string. Calling EnterSection("") will 49 //! stop the currently running sub section timer. The total time will still 50 //! keep running. 51 //! 52 //! When SectionedScopedTimer goes out of scope it will print a table of its 53 //! elapsed time and the sub sections. 54 //! 55 //! It only prints times if the time is greater than the threshold. Each 56 //! section is only printed if its time is greater than the threshold. The 57 //! whole table is only printed if the total time is greater than the threshold. 58 //! 59 //! The following is a usage example. It shows how to create timer with a 60 //! section before a loop, two sections in a loop, a section after a loop and a 61 //! section that will not be timed. 62 //! 63 //! ```{.cpp} 64 //! void function_to_profile () { 65 //! 66 //! SectionedScopedTimer timer("Title"); 67 //! timer.EnterSection("initial section"); 68 //! 69 //! profiled_code(); 70 //! 71 //! for () { 72 //! timer.EnterSection("for loop 1 section"); 73 //! 74 //! more_code(); 75 //! 76 //! timer.EnterSection("for loop 2 section"); 77 //! 78 //! even_more_code(); 79 //! } 80 //! 81 //! timer.EnterSection(""); // don't time this section 82 //! 83 //! untimed_code(); 84 //! 85 //! timer.EnterSection("final section"); 86 //! 87 //! final_timed_code() 88 //! } 89 //! ``` 90 //! 91 //! The tables of times will look like the following: 92 //! 93 //! ```{.txt} 94 //! Title - initial section time: xxxx ms 95 //! Title - for loop 1 section time: xxxx ms 96 //! Title - for loop 2 section time: xxxx ms 97 //! Title - final section time: xxxx ms 98 //! Title time: xxxx ms 99 //! ``` 100 class FO_COMMON_API SectionedScopedTimer { 101 public: 102 explicit SectionedScopedTimer(const std::string& timed_name, 103 std::chrono::microseconds threshold = std::chrono::milliseconds(1), 104 bool enable_output = true, 105 bool unify_section_duration_units = true); 106 ~SectionedScopedTimer(); 107 108 //! Start recording times for @p section_name. 109 //! 110 //! This can be called multiple times to add more time to a previously 111 //! created section. Use this feature to profile separate parts of loop 112 //! strucures. 113 void EnterSection(const std::string& section_name); 114 115 private: 116 class Impl; 117 118 std::unique_ptr<Impl> const m_impl; 119 }; 120 121 #endif // _ScopedTimer_h_ 122