CLI11
C++11 Command Line Interface Parser
Timer.hpp
1 #pragma once
2 
3 // Distributed under the 3-Clause BSD License. See accompanying
4 // file LICENSE or https://github.com/CLIUtils/CLI11 for details.
5 
6 // On GCC < 4.8, the following define is often missing. Due to the
7 // fact that this library only uses sleep_for, this should be safe
8 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 && __GNUC_MINOR__ < 8
9 #define _GLIBCXX_USE_NANOSLEEP
10 #endif
11 
12 #include <array>
13 #include <chrono>
14 #include <functional>
15 #include <iostream>
16 #include <string>
17 #include <utility>
18 
19 namespace CLI {
20 
22 class Timer {
23  protected:
25  using clock = std::chrono::steady_clock;
26 
28  using time_point = std::chrono::time_point<clock>;
29 
31  using time_print_t = std::function<std::string(std::string, std::string)>;
32 
34  std::string title_;
35 
38 
41 
43  size_t cycles{1};
44 
45  public:
47  static std::string Simple(std::string title, std::string time) { return title + ": " + time; }
48 
50  static std::string Big(std::string title, std::string time) {
51  return std::string("-----------------------------------------\n") + "| " + title + " | Time = " + time + "\n" +
52  "-----------------------------------------";
53  }
54 
55  public:
57  Timer(std::string title = "Timer", time_print_t time_print = Simple)
58  : title_(std::move(title)), time_print_(std::move(time_print)), start_(clock::now()) {}
59 
61  std::string time_it(std::function<void()> f, double target_time = 1) {
62  time_point start = start_;
63  double total_time;
64 
65  start_ = clock::now();
66  size_t n = 0;
67  do {
68  f();
69  std::chrono::duration<double> elapsed = clock::now() - start_;
70  total_time = elapsed.count();
71  } while(n++ < 100u && total_time < target_time);
72 
73  std::string out = make_time_str(total_time / static_cast<double>(n)) + " for " + std::to_string(n) + " tries";
74  start_ = start;
75  return out;
76  }
77 
79  std::string make_time_str() const {
80  time_point stop = clock::now();
81  std::chrono::duration<double> elapsed = stop - start_;
82  double time = elapsed.count() / static_cast<double>(cycles);
83  return make_time_str(time);
84  }
85 
86  // LCOV_EXCL_START
88  std::string make_time_str(double time) const {
89  auto print_it = [](double x, std::string unit) {
90  std::array<char, 50> buffer;
91  std::snprintf(buffer.data(), 50, "%.5g", x);
92  return buffer.data() + std::string(" ") + unit;
93  };
94 
95  if(time < .000001)
96  return print_it(time * 1000000000, "ns");
97  else if(time < .001)
98  return print_it(time * 1000000, "us");
99  else if(time < 1)
100  return print_it(time * 1000, "ms");
101  else
102  return print_it(time, "s");
103  }
104  // LCOV_EXCL_END
105 
107  std::string to_string() const { return time_print_(title_, make_time_str()); }
108 
110  Timer &operator/(size_t val) {
111  cycles = val;
112  return *this;
113  }
114 };
115 
117 class AutoTimer : public Timer {
118  public:
120  AutoTimer(std::string title = "Timer", time_print_t time_print = Simple) : Timer(title, time_print) {}
121  // GCC 4.7 does not support using inheriting constructors.
122 
124  ~AutoTimer() { std::cout << to_string() << std::endl; }
125 };
126 
127 } // namespace CLI
128 
130 inline std::ostream &operator<<(std::ostream &in, const CLI::Timer &timer) { return in << timer.to_string(); }
static std::string Big(std::string title, std::string time)
This is a fancy print function with — headers.
Definition: Timer.hpp:50
std::string to_string() const
This is the main function, it creates a string.
Definition: Timer.hpp:107
std::chrono::steady_clock clock
This is a typedef to make clocks easier to use.
Definition: Timer.hpp:25
static std::string Simple(std::string title, std::string time)
Standard print function, this one is set by default.
Definition: Timer.hpp:47
std::string make_time_str(double time) const
This prints out a time string from a time.
Definition: Timer.hpp:88
AutoTimer(std::string title="Timer", time_print_t time_print=Simple)
Reimplementing the constructor is required in GCC 4.7.
Definition: Timer.hpp:120
std::chrono::time_point< clock > time_point
This typedef is for points in time.
Definition: Timer.hpp:28
std::string make_time_str() const
This formats the numerical value for the time string.
Definition: Timer.hpp:79
This class prints out the time upon destruction.
Definition: Timer.hpp:117
std::string time_it(std::function< void()> f, double target_time=1)
Time a function by running it multiple times. Target time is the len to target.
Definition: Timer.hpp:61
Timer(std::string title="Timer", time_print_t time_print=Simple)
Standard constructor, can set title and print function.
Definition: Timer.hpp:57
size_t cycles
This is the number of times cycles (print divides by this number)
Definition: Timer.hpp:43
time_print_t time_print_
This is the function that is used to format most of the timing message.
Definition: Timer.hpp:37
std::ostream & operator<<(std::ostream &in, const T &item)
output streaming for enumerations
Definition: StringTools.hpp:23
std::function< std::string(std::string, std::string)> time_print_t
This is the type of a printing function, you can make your own.
Definition: Timer.hpp:31
time_point start_
This is the starting point (when the timer was created)
Definition: Timer.hpp:40
std::string title_
This is the title of the timer.
Definition: Timer.hpp:34
~AutoTimer()
This destructor prints the string.
Definition: Timer.hpp:124
Timer & operator/(size_t val)
Division sets the number of cycles to divide by (no graphical change)
Definition: Timer.hpp:110
This is a simple timer with pretty printing. Creating the timer starts counting.
Definition: Timer.hpp:22