1 /*++
2 Copyright (c) 2008 Microsoft Corporation
3 
4 Module Name:
5 
6     stopwatch.h
7 
8 Abstract:
9 
10     High resolution time keeping
11 
12 Author:
13 
14     Christoph Wintersteiger (t-cwinte) 2008-12-24
15 
16 Revision History:
17 
18 --*/
19 
20 #pragma once
21 
22 #include "util/debug.h"
23 #include <chrono>
24 #include <iostream>
25 #include<iomanip>
26 
27 
28 class stopwatch
29 {
30     typedef decltype(std::chrono::steady_clock::now()) clock_t;
31     typedef decltype(std::chrono::steady_clock::now() - std::chrono::steady_clock::now()) duration_t;
32 
33     clock_t m_start;
34     duration_t m_elapsed;
35     bool m_running = false;
36 
37     // FIXME: just use auto with VS 2015+
get()38     static clock_t get() {
39         return std::chrono::steady_clock::now();
40     }
41 
42 public:
stopwatch()43     stopwatch() {
44         reset();
45     }
46 
add(const stopwatch & s)47     void add(const stopwatch &s) {
48         m_elapsed += s.m_elapsed;
49     }
50 
reset()51     void reset() {
52         m_elapsed = duration_t::zero();
53     }
54 
start()55     void start() {
56         if (!m_running) {
57             m_start = get();
58             m_running = true;
59         }
60     }
61 
stop()62     void stop() {
63         if (m_running) {
64             m_elapsed += get() - m_start;
65             m_running = false;
66         }
67     }
68 
get_seconds()69     double get_seconds() const {
70         if (m_running) {
71             const_cast<stopwatch*>(this)->stop();
72             const_cast<stopwatch*>(this)->start();
73         }
74         return std::chrono::duration_cast<std::chrono::milliseconds>(m_elapsed).count() / 1000.0;
75     }
76 
get_current_seconds()77     double get_current_seconds() const {
78         return get_seconds();
79     }
80 };
81 
82 
83 struct scoped_watch {
84     stopwatch &m_sw;
m_swscoped_watch85     scoped_watch (stopwatch &sw, bool reset=false): m_sw(sw) {
86         if (reset) m_sw.reset();
87         m_sw.start();
88     }
~scoped_watchscoped_watch89     ~scoped_watch() {
90         m_sw.stop ();
91     }
92 };
93 
94 inline std::ostream& operator<<(std::ostream& out, stopwatch const& sw) {
95     return out << " :time " << std::fixed << std::setprecision(2) << sw.get_seconds();
96 }
97 
98 
99