CLI11
C++11 Command Line Interface Parser
Loading...
Searching...
No Matches
Timer.hpp
1// Copyright (c) 2017-2024, 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// IWYU pragma: private, include "CLI/CLI.hpp"
10
11// On GCC < 4.8, the following define is often missing. Due to the
12// fact that this library only uses sleep_for, this should be safe
13#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 && __GNUC_MINOR__ < 8
14#define _GLIBCXX_USE_NANOSLEEP
15#endif
16
17#include <cmath>
18
19#include <array>
20#include <chrono>
21#include <functional>
22#include <iostream>
23#include <string>
24#include <utility>
25
26namespace CLI {
27
29class Timer {
30 protected:
32 using clock = std::chrono::steady_clock;
33
35 using time_point = std::chrono::time_point<clock>;
36
38 using time_print_t = std::function<std::string(std::string, std::string)>;
39
41 std::string title_;
42
45
48
50 std::size_t cycles{1};
51
52 public:
54 static std::string Simple(std::string title, std::string time) { return title + ": " + time; }
55
57 static std::string Big(std::string title, std::string time) {
58 return std::string("-----------------------------------------\n") + "| " + title + " | Time = " + time + "\n" +
59 "-----------------------------------------";
60 }
61
62 public:
64 explicit Timer(std::string title = "Timer", time_print_t time_print = Simple)
65 : title_(std::move(title)), time_print_(std::move(time_print)), start_(clock::now()) {}
66
68 std::string time_it(std::function<void()> f, double target_time = 1) {
69 time_point start = start_;
70 double total_time = NAN;
71
72 start_ = clock::now();
73 std::size_t n = 0;
74 do {
75 f();
76 std::chrono::duration<double> elapsed = clock::now() - start_;
77 total_time = elapsed.count();
78 } while(n++ < 100u && total_time < target_time);
79
80 std::string out = make_time_str(total_time / static_cast<double>(n)) + " for " + std::to_string(n) + " tries";
81 start_ = start;
82 return out;
83 }
84
86 std::string make_time_str() const { // NOLINT(modernize-use-nodiscard)
87 time_point stop = clock::now();
88 std::chrono::duration<double> elapsed = stop - start_;
89 double time = elapsed.count() / static_cast<double>(cycles);
90 return make_time_str(time);
91 }
92
93 // LCOV_EXCL_START
95 std::string make_time_str(double time) const { // NOLINT(modernize-use-nodiscard)
96 auto print_it = [](double x, std::string unit) {
97 const unsigned int buffer_length = 50;
98 std::array<char, buffer_length> buffer;
99 std::snprintf(buffer.data(), buffer_length, "%.5g", x);
100 return buffer.data() + std::string(" ") + unit;
101 };
102
103 if(time < .000001)
104 return print_it(time * 1000000000, "ns");
105 if(time < .001)
106 return print_it(time * 1000000, "us");
107 if(time < 1)
108 return print_it(time * 1000, "ms");
109 return print_it(time, "s");
110 }
111 // LCOV_EXCL_STOP
112
114 std::string to_string() const { return time_print_(title_, make_time_str()); } // NOLINT(modernize-use-nodiscard)
115
117 Timer &operator/(std::size_t val) {
118 cycles = val;
119 return *this;
120 }
121};
122
124class AutoTimer : public Timer {
125 public:
127 explicit AutoTimer(std::string title = "Timer", time_print_t time_print = Simple) : Timer(title, time_print) {}
128 // GCC 4.7 does not support using inheriting constructors.
129
131 ~AutoTimer() { std::cout << to_string() << '\n'; }
132};
133
134} // namespace CLI
135
137inline std::ostream &operator<<(std::ostream &in, const CLI::Timer &timer) { return in << timer.to_string(); }
This class prints out the time upon destruction.
Definition Timer.hpp:124
AutoTimer(std::string title="Timer", time_print_t time_print=Simple)
Reimplementing the constructor is required in GCC 4.7.
Definition Timer.hpp:127
~AutoTimer()
This destructor prints the string.
Definition Timer.hpp:131
This is a simple timer with pretty printing. Creating the timer starts counting.
Definition Timer.hpp:29
time_print_t time_print_
This is the function that is used to format most of the timing message.
Definition Timer.hpp:44
Timer(std::string title="Timer", time_print_t time_print=Simple)
Standard constructor, can set title and print function.
Definition Timer.hpp:64
time_point start_
This is the starting point (when the timer was created)
Definition Timer.hpp:47
std::string title_
This is the title of the timer.
Definition Timer.hpp:41
std::string make_time_str() const
This formats the numerical value for the time string.
Definition Timer.hpp:86
std::string to_string() const
This is the main function, it creates a string.
Definition Timer.hpp:114
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:38
std::size_t cycles
This is the number of times cycles (print divides by this number)
Definition Timer.hpp:50
std::string make_time_str(double time) const
This prints out a time string from a time.
Definition Timer.hpp:95
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:68
std::chrono::steady_clock clock
This is a typedef to make clocks easier to use.
Definition Timer.hpp:32
Timer & operator/(std::size_t val)
Division sets the number of cycles to divide by (no graphical change)
Definition Timer.hpp:117
static std::string Big(std::string title, std::string time)
This is a fancy print function with — headers.
Definition Timer.hpp:57
std::chrono::time_point< clock > time_point
This typedef is for points in time.
Definition Timer.hpp:35
static std::string Simple(std::string title, std::string time)
Standard print function, this one is set by default.
Definition Timer.hpp:54
std::ostream & operator<<(std::ostream &in, const T &item)
output streaming for enumerations
Definition StringTools.hpp:34