CLI11  2.3.2
Timer.hpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner
2 // under NSF AWARD 1414736 and by the respective contributors.
3 // All rights reserved.
4 //
5 // SPDX-License-Identifier: BSD-3-Clause
6 
7 #pragma once
8 
9 // On GCC < 4.8, the following define is often missing. Due to the
10 // fact that this library only uses sleep_for, this should be safe
11 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 && __GNUC_MINOR__ < 8
12 #define _GLIBCXX_USE_NANOSLEEP
13 #endif
14 
15 #include <cmath>
16 
17 #include <array>
18 #include <chrono>
19 #include <functional>
20 #include <iostream>
21 #include <string>
22 #include <utility>
23 
24 namespace CLI {
25 
27 class Timer {
28  protected:
30  using clock = std::chrono::steady_clock;
31 
33  using time_point = std::chrono::time_point<clock>;
34 
36  using time_print_t = std::function<std::string(std::string, std::string)>;
37 
39  std::string title_;
40 
43 
46 
48  std::size_t cycles{1};
49 
50  public:
52  static std::string Simple(std::string title, std::string time) { return title + ": " + time; }
53 
55  static std::string Big(std::string title, std::string time) {
56  return std::string("-----------------------------------------\n") + "| " + title + " | Time = " + time + "\n" +
57  "-----------------------------------------";
58  }
59 
60  public:
62  explicit Timer(std::string title = "Timer", time_print_t time_print = Simple)
63  : title_(std::move(title)), time_print_(std::move(time_print)), start_(clock::now()) {}
64 
66  std::string time_it(std::function<void()> f, double target_time = 1) {
67  time_point start = start_;
68  double total_time = NAN;
69 
70  start_ = clock::now();
71  std::size_t n = 0;
72  do {
73  f();
74  std::chrono::duration<double> elapsed = clock::now() - start_;
75  total_time = elapsed.count();
76  } while(n++ < 100u && total_time < target_time);
77 
78  std::string out = make_time_str(total_time / static_cast<double>(n)) + " for " + std::to_string(n) + " tries";
79  start_ = start;
80  return out;
81  }
82 
84  std::string make_time_str() const { // NOLINT(modernize-use-nodiscard)
85  time_point stop = clock::now();
86  std::chrono::duration<double> elapsed = stop - start_;
87  double time = elapsed.count() / static_cast<double>(cycles);
88  return make_time_str(time);
89  }
90 
91  // LCOV_EXCL_START
93  std::string make_time_str(double time) const { // NOLINT(modernize-use-nodiscard)
94  auto print_it = [](double x, std::string unit) {
95  const unsigned int buffer_length = 50;
96  std::array<char, buffer_length> buffer;
97  std::snprintf(buffer.data(), buffer_length, "%.5g", x);
98  return buffer.data() + std::string(" ") + unit;
99  };
100 
101  if(time < .000001)
102  return print_it(time * 1000000000, "ns");
103  if(time < .001)
104  return print_it(time * 1000000, "us");
105  if(time < 1)
106  return print_it(time * 1000, "ms");
107  return print_it(time, "s");
108  }
109  // LCOV_EXCL_STOP
110 
112  std::string to_string() const { return time_print_(title_, make_time_str()); } // NOLINT(modernize-use-nodiscard)
113 
115  Timer &operator/(std::size_t val) {
116  cycles = val;
117  return *this;
118  }
119 };
120 
122 class AutoTimer : public Timer {
123  public:
125  explicit AutoTimer(std::string title = "Timer", time_print_t time_print = Simple) : Timer(title, time_print) {}
126  // GCC 4.7 does not support using inheriting constructors.
127 
129  ~AutoTimer() { std::cout << to_string() << std::endl; }
130 };
131 
132 } // namespace CLI
133 
135 inline std::ostream &operator<<(std::ostream &in, const CLI::Timer &timer) { return in << timer.to_string(); }
Timer(std::string title="Timer", time_print_t time_print=Simple)
Standard constructor, can set title and print function.
Definition: Timer.hpp:62
Definition: App.hpp:34
Timer & operator/(std::size_t val)
Division sets the number of cycles to divide by (no graphical change)
Definition: Timer.hpp:115
std::string to_string() const
This is the main function, it creates a string.
Definition: Timer.hpp:112
STL namespace.
This class prints out the time upon destruction.
Definition: Timer.hpp:122
std::string make_time_str(double time) const
This prints out a time string from a time.
Definition: Timer.hpp:93
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: TypeTools.hpp:281
static std::string Big(std::string title, std::string time)
This is a fancy print function with — headers.
Definition: Timer.hpp:55
std::chrono::steady_clock clock
This is a typedef to make clocks easier to use.
Definition: Timer.hpp:30
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:66
std::string make_time_str() const
This formats the numerical value for the time string.
Definition: Timer.hpp:84
std::size_t cycles
This is the number of times cycles (print divides by this number)
Definition: Timer.hpp:48
~AutoTimer()
This destructor prints the string.
Definition: Timer.hpp:129
static std::string Simple(std::string title, std::string time)
Standard print function, this one is set by default.
Definition: Timer.hpp:52
std::string title_
This is the title of the timer.
Definition: Timer.hpp:39
std::ostream & operator<<(std::ostream &in, const CLI::Timer &timer)
This prints out the time if shifted into a std::cout like stream.
Definition: Timer.hpp:135
time_point start_
This is the starting point (when the timer was created)
Definition: Timer.hpp:45
This is a simple timer with pretty printing. Creating the timer starts counting.
Definition: Timer.hpp:27
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:36
time_print_t time_print_
This is the function that is used to format most of the timing message.
Definition: Timer.hpp:42
std::chrono::time_point< clock > time_point
This typedef is for points in time.
Definition: Timer.hpp:33
AutoTimer(std::string title="Timer", time_print_t time_print=Simple)
Reimplementing the constructor is required in GCC 4.7.
Definition: Timer.hpp:125