ra4_draw  4bd0201e3d922d42bd545d4b045ed44db33454a4
timer.cpp
Go to the documentation of this file.
1 #include "core/timer.hpp"
2 
3 #include <cmath>
4 
5 #include <iostream>
6 #include <iomanip>
7 
8 using namespace std;
9 
10 namespace{
11  void PrintTime(ostream &stream, double seconds){
12  int seconds_round = round(seconds);
13  int hours = seconds_round/3600;
14  seconds_round -= 3600*hours;
15  int minutes = seconds_round/60;
16  seconds_round -= 60*minutes;
17  auto fill = stream.fill();
18  stream.fill('0');
19  if(hours){
20  stream << hours << ':' << setw(2) << minutes << ':' << setw(2) << seconds_round;
21  }else{
22  stream << minutes << ':' << setw(2) << seconds_round;
23  }
24  stream.fill(fill);
25  }
26 }
27 
28 mutex Timer::mutex_{};
29 
30 Timer::Timer(size_t num_iterations,
31  double auto_print,
32  bool erase_lines):
33  label_(),
34  start_time_(Clock::now()),
35  last_print_(start_time_),
36  iteration_(static_cast<size_t>(-1)),
37  num_iterations_(num_iterations),
38  auto_print_(auto_print),
39  erase_lines_(erase_lines){
40  }
41 
42 Timer::Timer(size_t num_iterations,
43  chrono::duration<double> auto_print,
44  bool erase_lines):
45  label_(),
46  start_time_(Clock::now()),
47  last_print_(start_time_),
48  iteration_(static_cast<size_t>(-1)),
49  num_iterations_(num_iterations),
50  auto_print_(auto_print),
51  erase_lines_(erase_lines){
52  }
53 
54 Timer::Timer(const string &label,
55  size_t num_iterations,
56  double auto_print,
57  bool erase_lines):
58  label_(label),
59  start_time_(Clock::now()),
60  last_print_(start_time_),
61  iteration_(static_cast<size_t>(-1)),
62  num_iterations_(num_iterations),
63  auto_print_(auto_print),
64  erase_lines_(erase_lines){
65  }
66 
67 Timer::Timer(const string &label,
68  size_t num_iterations,
69  chrono::duration<double> auto_print,
70  bool erase_lines):
71  label_(label),
72  start_time_(Clock::now()),
73  last_print_(start_time_),
74  iteration_(static_cast<size_t>(-1)),
75  num_iterations_(num_iterations),
76  auto_print_(auto_print),
77  erase_lines_(erase_lines){
78  }
79 
81  ++iteration_;
82  if(auto_print_.count() >= 0.
83  && chrono::duration<double>(Clock::now() - last_print_) >= auto_print_){
84  if(erase_lines_) clog << "\r\33[2K" << *this;
85  else clog << *this << '\n';
86  }
87 }
88 
90  iteration_ = -1;
91  start_time_ = Clock::now();
92  last_print_ = start_time_;
93 }
94 
95 void Timer::Restart(size_t num_iterations){
96  num_iterations_ = num_iterations;
97  iteration_ = -1;
98  start_time_ = Clock::now();
99  last_print_ = start_time_;
100 }
101 
102 chrono::duration<double> Timer::ElapsedTime() const{
103  return chrono::duration<double>(Clock::now() - start_time_);
104 }
105 
106 chrono::duration<double> Timer::RemainingTime() const{
107  if(iteration_ == static_cast<size_t>(-1) || iteration_ == 0){
108  return static_cast<chrono::duration<double> >(0.);
109  }else{
110  return ElapsedTime()*(num_iterations_ - iteration_)/iteration_;
111  }
112 }
113 
114 ostream & operator<<(ostream &stream, const Timer &timer){
115  double elapsed = timer.ElapsedTime().count();
116  double remaining = timer.RemainingTime().count();
117  auto eta_raw = chrono::system_clock::now()
118  +static_cast<chrono::seconds>(static_cast<chrono::seconds::rep>(remaining));
119  auto eta_time = chrono::system_clock::to_time_t(eta_raw);
120  string eta = ctime(&eta_time);
121  if(eta.size() && eta.back() == '\n') eta.pop_back();
122  {
123  lock_guard<mutex> lock(Timer::mutex_);
124  if(timer.Label() != "") stream << timer.Label() << ": ";
125  stream << timer.Iteration() << '/' << timer.NumIterations() << " in ";
126  PrintTime(stream, elapsed);
127  auto precision = stream.precision();
128  stream.precision(3);
129  if(timer.NumIterations()){
130  stream << " (" << 100.*timer.Iteration()/timer.NumIterations() << "%, ";
131  }else{
132  stream << " (" << 100. << "%, ";
133  }
134  if(elapsed > 0.){
135  stream << timer.Iteration()/elapsed << " Hz). ";
136  }else{
137  stream << 0. << " Hz). ";
138  }
139  stream.precision(precision);
140  PrintTime(stream, remaining);
141  stream << " left. ETA: " << eta;
142  }
143  timer.last_print_ = Timer::Clock::now();
144  return stream;
145 }
146 
147 size_t Timer::Iteration() const{
148  return iteration_;
149 }
150 
151 Timer & Timer::Iteration(size_t iteration){
152  iteration_ = iteration;
153  return *this;
154 }
155 
156 size_t Timer::NumIterations() const{
157  return num_iterations_;
158 }
159 
160 Timer & Timer::NumIterations(size_t num_iterations){
161  num_iterations_ = num_iterations;
162  return *this;
163 }
164 
165 chrono::duration<double> Timer::AutoPrintTime() const{
166  return auto_print_;
167 }
168 
169 Timer & Timer::AutoPrintTime(double auto_print){
170  auto_print_ = static_cast<chrono::duration<double> >(auto_print);
171  return *this;
172 }
173 
174 Timer & Timer::AutoPrintTime(chrono::duration<double> auto_print){
175  auto_print_ = auto_print;
176  return *this;
177 }
178 
179 const std::string & Timer::Label() const{
180  return label_;
181 }
182 
183 Timer & Timer::Label(const std::string &label){
184  label_ = label;
185  return *this;
186 }
void PrintTime(ostream &stream, double seconds)
Definition: timer.cpp:11
Definition: timer.hpp:9
std::chrono::duration< double > AutoPrintTime() const
Definition: timer.cpp:165
STL namespace.
std::size_t Iteration() const
Definition: timer.cpp:147
Timer(std::size_t num_iterations=0, double auto_print=-1., bool erase_lines=false)
std::chrono::duration< double > RemainingTime() const
Definition: timer.cpp:106
TimeType last_print_
Definition: timer.hpp:60
const std::string & Label() const
Definition: timer.cpp:179
void Restart()
Definition: timer.cpp:89
std::chrono::duration< double > ElapsedTime() const
Definition: timer.cpp:102
void Iterate()
Definition: timer.cpp:80
static std::mutex mutex_
Definition: timer.hpp:64
std::size_t NumIterations() const
Definition: timer.cpp:156
ostream & operator<<(ostream &stream, const Timer &timer)
Definition: timer.cpp:114