File indexing completed on 2026-11-15 10:10:56
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010
0011 #include <cmath>
0012
0013 #include <array>
0014 #include <chrono>
0015 #include <cstdio>
0016 #include <functional>
0017 #include <iostream>
0018 #include <string>
0019 #include <utility>
0020
0021 namespace CLI {
0022
0023
0024 class Timer {
0025 protected:
0026
0027 using clock = std::chrono::steady_clock;
0028
0029
0030 using time_point = std::chrono::time_point<clock>;
0031
0032
0033 using time_print_t = std::function<std::string(std::string, std::string)>;
0034
0035
0036 std::string title_;
0037
0038
0039 time_print_t time_print_;
0040
0041
0042 time_point start_;
0043
0044
0045 std::size_t cycles{1};
0046
0047 public:
0048
0049 static std::string Simple(std::string title, std::string time) { return title + ": " + time; }
0050
0051
0052 static std::string Big(std::string title, std::string time) {
0053 return std::string("-----------------------------------------\n") + "| " + title + " | Time = " + time + "\n" +
0054 "-----------------------------------------";
0055 }
0056
0057 public:
0058
0059 explicit Timer(std::string title = "Timer", time_print_t time_print = Simple)
0060 : title_(std::move(title)), time_print_(std::move(time_print)), start_(clock::now()) {}
0061
0062
0063 std::string time_it(std::function<void()> f, double target_time = 1) {
0064 time_point start = start_;
0065 double total_time = NAN;
0066
0067 start_ = clock::now();
0068 std::size_t n = 0;
0069 do {
0070 f();
0071 std::chrono::duration<double> elapsed = clock::now() - start_;
0072 total_time = elapsed.count();
0073 } while(n++ < 100u && total_time < target_time);
0074
0075 std::string out = make_time_str(total_time / static_cast<double>(n)) + " for " + std::to_string(n) + " tries";
0076 start_ = start;
0077 return out;
0078 }
0079
0080
0081 std::string make_time_str() const {
0082 time_point stop = clock::now();
0083 std::chrono::duration<double> elapsed = stop - start_;
0084 double time = elapsed.count() / static_cast<double>(cycles);
0085 return make_time_str(time);
0086 }
0087
0088
0089
0090 std::string make_time_str(double time) const {
0091 auto print_it = [](double x, std::string unit) {
0092 const unsigned int buffer_length = 50;
0093 std::array<char, buffer_length> buffer;
0094 std::snprintf(buffer.data(), buffer_length, "%.5g", x);
0095 return buffer.data() + std::string(" ") + unit;
0096 };
0097
0098 if(time < .000001)
0099 return print_it(time * 1000000000, "ns");
0100 if(time < .001)
0101 return print_it(time * 1000000, "us");
0102 if(time < 1)
0103 return print_it(time * 1000, "ms");
0104 return print_it(time, "s");
0105 }
0106
0107
0108
0109 std::string to_string() const { return time_print_(title_, make_time_str()); }
0110
0111
0112 Timer &operator/(std::size_t val) {
0113 cycles = val;
0114 return *this;
0115 }
0116 };
0117
0118
0119 class AutoTimer : public Timer {
0120 public:
0121 using Timer::Timer;
0122
0123
0124 ~AutoTimer() { std::cout << to_string() << '\n'; }
0125 };
0126
0127 }
0128
0129
0130 inline std::ostream &operator<<(std::ostream &in, const CLI::Timer &timer) { return in << timer.to_string(); }