C++11 tidying.
[dcpomatic.git] / src / lib / timer.cc
1 /*
2     Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 /** @file src/timer.cc
23  *  @brief Some timing classes for debugging and profiling.
24  */
25
26
27 #include "compose.hpp"
28 #include "timer.h"
29 #include "util.h"
30 #include <sys/time.h>
31 #include <iostream>
32
33 #include "i18n.h"
34
35
36 using std::cout;
37 using std::list;
38 using std::max;
39 using std::pair;
40 using std::string;
41 using boost::optional;
42
43
44 /** @param n Name to use when giving output */
45 PeriodTimer::PeriodTimer (string n)
46         : _name (n)
47 {
48         gettimeofday (&_start, 0);
49 }
50
51
52 /** Destroy PeriodTimer and output the time elapsed since its construction */
53 PeriodTimer::~PeriodTimer ()
54 {
55         struct timeval stop;
56         gettimeofday (&stop, 0);
57         cout << N_("T: ") << _name << N_(": ") << (seconds (stop) - seconds (_start)) << N_("\n");
58 }
59
60
61 StateTimer::StateTimer (string n, string s)
62         : _name (n)
63 {
64         struct timeval t;
65         gettimeofday (&t, 0);
66         _time = seconds (t);
67         _state = s;
68 }
69
70
71 StateTimer::StateTimer (string n)
72         : _name (n)
73 {
74
75 }
76
77
78 void
79 StateTimer::set (string s)
80 {
81         set_internal (s);
82 }
83
84
85 void
86 StateTimer::set_internal (optional<string> s)
87 {
88         double const last = _time;
89         struct timeval t;
90         gettimeofday (&t, 0);
91         _time = seconds (t);
92
93         if (s && _counts.find(*s) == _counts.end()) {
94                 _counts[*s] = Counts();
95         }
96
97         if (_state) {
98                 _counts[*_state].total_time += _time - last;
99                 _counts[*_state].number++;
100         }
101         _state = s;
102 }
103
104
105 void
106 StateTimer::unset ()
107 {
108         set_internal (optional<string>());
109 }
110
111
112 /** Destroy StateTimer and generate a summary of the state timings on cout */
113 StateTimer::~StateTimer ()
114 {
115         if (!_state) {
116                 return;
117         }
118
119         unset ();
120
121         int longest = 0;
122         for (auto const& i: _counts) {
123                 longest = max (longest, int(i.first.length()));
124         }
125
126         list<pair<double, string>> sorted;
127
128         for (auto const& i: _counts) {
129                 string name = i.first + string(longest + 1 - i.first.size(), ' ');
130                 char buffer[64];
131                 snprintf (buffer, 64, "%.4f", i.second.total_time);
132                 string total_time (buffer);
133                 sorted.push_back (make_pair(i.second.total_time, String::compose("\t%1%2 %3 %4", name, total_time, i.second.number, (i.second.total_time / i.second.number))));
134         }
135
136         sorted.sort ([](pair<double, string> const& a, pair<double, string> const& b) {
137                 return a.first > b.first;
138         });
139
140
141         cout << _name << N_(":\n");
142         for (auto const& i: sorted) {
143                 cout << N_("\t") << i.second << "\n";
144         }
145 }