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