Thrill  0.1
stats_timer.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * thrill/common/stats_timer.hpp
3  *
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * Part of Project Thrill - http://project-thrill.org
9  *
10  * Copyright (C) 2014 Thomas Keh <[email protected]>
11  * Copyright (C) 2015 Timo Bingmann <[email protected]>
12  *
13  * All rights reserved. Published under the BSD-2 license in the LICENSE file.
14  ******************************************************************************/
15 
16 #pragma once
17 #ifndef THRILL_COMMON_STATS_TIMER_HEADER
18 #define THRILL_COMMON_STATS_TIMER_HEADER
19 
22 
23 #include <cassert>
24 #include <chrono>
25 #include <ostream>
26 
27 namespace thrill {
28 namespace common {
29 
30 /*!
31  * This class provides a statistical stop watch timer that can easily be
32  * deactivated using a boolean template switch.
33  *
34  * It uses std::chrono to get the current time when start() is called. Then,
35  * after some processing, the function stop() functions can be called, or
36  * seconds() and other accessors can be called directly.
37  */
38 template <bool Active>
40 
41 template <>
42 class StatsTimerBase<true>
43 {
44 public:
45  using steady_clock = std::chrono::steady_clock;
46  using time_point = std::chrono::steady_clock::time_point;
47 
48  using duration = std::chrono::microseconds;
49 
50 protected:
51  //! boolean whether the timer is currently running
53 
54  //! total accumulated time in microseconds.
56 
57  //! last start time of the stop watch
59 
60 public:
61  //! Initialize and optionally immediately start the timer
62  explicit StatsTimerBase(bool start_immediately)
63  : running_(false), accumulated_() {
64  if (start_immediately) Start();
65  }
66 
67  //! move-constructor: default
68  StatsTimerBase(StatsTimerBase&&) = default;
69  //! move-assignment operator: default
70  StatsTimerBase& operator = (StatsTimerBase&&) = default;
71 
72  //! Whether the timer is real
73  bool Real() const { return true; }
74 
75  //! Whether the timer is running
76  bool running() const {
77  return running_;
78  }
79 
80  //! start timer
82  assert(!running_);
83  running_ = true;
84  last_start_ = steady_clock::now();
85  return *this;
86  }
87 
88  //! start timer only if it not running
90  if (!running_) {
91  running_ = true;
92  last_start_ = steady_clock::now();
93  }
94  return *this;
95  }
96 
97  //! stop timer
99  assert(running_);
100  running_ = false;
101  accumulated_ += std::chrono::duration_cast<duration>(
102  steady_clock::now() - last_start_);
103  return *this;
104  }
105 
106  //! stop timer if it is running
108  if (running_)
109  Stop();
110  return *this;
111  }
112 
113  //! return accumulated time
115  accumulated_ = duration(0);
116  last_start_ = steady_clock::now();
117  return *this;
118  }
119 
120  //! return currently accumulated time
122  duration d = accumulated_;
123 
124  if (running_)
125  d += std::chrono::duration_cast<duration>(
126  steady_clock::now() - last_start_);
127 
128  return d;
129  }
130 
131  //! return currently accumulated time in microseconds
132  std::chrono::microseconds::rep Microseconds() const {
133  return std::chrono::duration_cast<std::chrono::microseconds>(
134  Accumulated()).count();
135  }
136 
137  //! return currently accumulated time in milliseconds
138  std::chrono::milliseconds::rep Milliseconds() const {
139  return std::chrono::duration_cast<std::chrono::milliseconds>(
140  Accumulated()).count();
141  }
142 
143  //! return currently accumulated time in seconds
144  std::chrono::seconds::rep Seconds() const {
145  return std::chrono::duration_cast<std::chrono::seconds>(
146  Accumulated()).count();
147  }
148 
149  //! return currently accumulated time in seconds as double with microseconds
150  //! precision
151  double SecondsDouble() const {
152  return static_cast<double>(Microseconds()) / 1e6;
153  }
154 
155  //! return currently accumulated time in seconds as double with microseconds
156  //! precision
157  double MillisecondsDouble() const {
158  return static_cast<double>(Microseconds()) / 1e3;
159  }
160 
161  //! accumulate elapsed time from another timer
163  accumulated_ += tm.accumulated_;
164  return *this;
165  }
166 
167  //! direct <<-operator for ostream. Can be used for printing with std::cout.
168  friend std::ostream& operator << (std::ostream& os, const StatsTimerBase& t) {
169  return os << t.SecondsDouble();
170  }
171 
172  friend JsonLine& Put(JsonLine& line, const StatsTimerBase& t) {
173  return Put(line, t.SecondsDouble());
174  }
175 };
176 
177 template <>
178 class StatsTimerBase<false>
179 {
180 public:
181  using steady_clock = std::chrono::steady_clock;
182  using time_point = std::chrono::steady_clock::time_point;
183 
184  using duration = std::chrono::microseconds;
185 
186  //! Initialize and optionally immediately start the timer
187  explicit StatsTimerBase(bool /* autostart */) { }
188 
189  //! move-constructor: default
190  StatsTimerBase(StatsTimerBase&&) = default;
191  //! move-assignment operator: default
192  StatsTimerBase& operator = (StatsTimerBase&&) = default;
193 
194  //! Whether the timer is real
195  bool Real() const { return false; }
196 
197  //! Whether the timer is running
198  bool running() const {
199  return false;
200  }
201 
202  //! start timer
204  return *this;
205  }
206 
207  //! start timer only if it not running
209  return *this;
210  }
211 
212  //! stop timer
214  return *this;
215  }
216 
217  //! stop timer if it is running
219  return *this;
220  }
221 
222  //! return accumulated time
224  return *this;
225  }
226 
227  //! return currently accumulated time
229  return duration();
230  }
231 
232  //! return currently accumulated time in microseconds
233  std::chrono::microseconds::rep Microseconds() const {
234  return 0;
235  }
236 
237  //! return currently accumulated time in milliseconds
238  std::chrono::milliseconds::rep Milliseconds() const {
239  return 0;
240  }
241 
242  //! return currently accumulated time in milliseconds
243  std::chrono::seconds::rep Seconds() const {
244  return 0;
245  }
246 
247  //! return currently accumulated time in seconds as double with microseconds
248  //! precision
249  double SecondsDouble() const {
250  return 0;
251  }
252 
253  double MillisecondsDouble() const { return 0; }
254 
255  //! accumulate elapsed time from another timer
257  return *this;
258  }
259 
260  //! direct <<-operator for ostream. Can be used for printing with std::cout.
261  friend std::ostream& operator << (std::ostream& os, const StatsTimerBase&) {
262  return os << "<invalid>";
263  }
264 
265  friend JsonLine& Put(JsonLine& line, const StatsTimerBase& t) {
266  return Put(line, t.SecondsDouble());
267  }
268 };
269 
270 template <bool Active>
271 class StatsTimerBaseStarted : public StatsTimerBase<Active>
272 {
273 public:
274  //! Initialize and automatically start the timer
276  : StatsTimerBase<Active>(/* start_immediately */ true) { }
277 };
278 
279 template <bool Active>
280 class StatsTimerBaseStopped : public StatsTimerBase<Active>
281 {
282 public:
283  //! Initialize but do NOT automatically start the timer
285  : StatsTimerBase<Active>(/* start_immediately */ false) { }
286 };
287 
291 
295 
296 //! RIAA class for running the timer until destruction
297 template <typename Timer>
298 class RunTimer
299 {
300 public:
301  explicit RunTimer(Timer& timer) : timer_(timer) { timer.Start(); }
302 
303  //! non-copyable: delete copy-constructor
304  RunTimer(const RunTimer&) = delete;
305  //! non-copyable: delete assignment operator
306  RunTimer& operator = (const RunTimer&) = delete;
307 
308  ~RunTimer() { timer_.Stop(); }
309 
310 private:
311  Timer& timer_;
312 };
313 
314 } // namespace common
315 } // namespace thrill
316 
317 #endif // !THRILL_COMMON_STATS_TIMER_HEADER
318 
319 /******************************************************************************/
StatsTimerBase(bool start_immediately)
Initialize and optionally immediately start the timer.
Definition: stats_timer.hpp:62
StatsTimerBase & Stop()
stop timer
friend JsonLine & Put(JsonLine &line, const StatsTimerBase &t)
common::AtomicMovable< bool > running_
boolean whether the timer is currently running
Definition: stats_timer.hpp:52
StatsTimerBase & StartEventually()
start timer only if it not running
StatsTimerBase & Start()
start timer
Definition: stats_timer.hpp:81
RIAA class for running the timer until destruction.
friend JsonLine & Put(JsonLine &line, const StatsTimerBase &t)
std::chrono::seconds::rep Seconds() const
return currently accumulated time in milliseconds
StatsTimerBase & Stop()
stop timer
Definition: stats_timer.hpp:98
std::chrono::steady_clock::time_point time_point
Definition: stats_timer.hpp:46
std::chrono::microseconds::rep Microseconds() const
return currently accumulated time in microseconds
uint_pair & operator+=(const uint_pair &b)
addition operator (uses 64-bit arithmetic)
Definition: uint_types.hpp:166
std::chrono::microseconds duration
Definition: stats_timer.hpp:48
std::chrono::steady_clock steady_clock
duration accumulated_
total accumulated time in microseconds.
Definition: stats_timer.hpp:55
StatsTimerBase(bool)
Initialize and optionally immediately start the timer.
StatsTimerBase & Reset()
return accumulated time
std::chrono::microseconds::rep Microseconds() const
return currently accumulated time in microseconds
time_point last_start_
last start time of the stop watch
Definition: stats_timer.hpp:58
bool running() const
Whether the timer is running.
duration Accumulated() const
return currently accumulated time
StatsTimerBaseStopped()
Initialize but do NOT automatically start the timer.
std::chrono::seconds::rep Seconds() const
return currently accumulated time in seconds
duration Accumulated() const
return currently accumulated time
std::chrono::steady_clock steady_clock
Definition: stats_timer.hpp:45
std::chrono::microseconds duration
StatsTimerBase & StopEventually()
stop timer if it is running
bool Real() const
Whether the timer is real.
Definition: stats_timer.hpp:73
StatsTimerBase & StartEventually()
start timer only if it not running
Definition: stats_timer.hpp:89
bool Real() const
Whether the timer is real.
std::chrono::milliseconds::rep Milliseconds() const
return currently accumulated time in milliseconds
static JsonLine & Put(JsonLine &line, bool const &value)
std::chrono::steady_clock::time_point time_point
std::chrono::milliseconds::rep Milliseconds() const
return currently accumulated time in milliseconds
bool running() const
Whether the timer is running.
Definition: stats_timer.hpp:76
StatsTimerBase & Reset()
return accumulated time
StatsTimerBase & StopEventually()
stop timer if it is running
StatsTimerBaseStarted()
Initialize and automatically start the timer.
This class provides a statistical stop watch timer that can easily be deactivated using a boolean tem...
Definition: stats_timer.hpp:39
std::ostream & operator<<(std::ostream &os, const DIABase &d)
make ostream-able.
Definition: dia_base.cpp:449
StatsTimerBase & Start()
start timer
JsonLine is an object used to aggregate a set of key:value pairs for output into a JSON log...