14#include "vipra/util/clock.hpp"
18#ifndef VIPRA_PERF_TESTING
22 static void add_call(std::string_view ) {}
23 static void start(std::string_view ) {}
24 static void stop(std::string_view ) {}
25 static auto report() -> std::string {
return ""; }
39 static void add_call(std::string_view name)
noexcept
41 if ( ! std::is_constant_evaluated() ) {
42 if ( get_calls().find(name) == get_calls().end() ) {
43 get_calls().emplace(std::string(name), 0);
45 (get_calls().find(name))->second++;
54 static void start(std::string_view name)
noexcept
56 if ( ! std::is_constant_evaluated() ) {
57 if ( get_clocks().find(name) == get_clocks().end() ) {
58 get_clocks().emplace(std::string(name), Util::Clock<Util::micro>{});
61 (get_clocks().find(name))->second.start();
70 static void stop(std::string_view name)
noexcept
72 if ( ! std::is_constant_evaluated() ) {
73 auto time = (get_clocks().find(name))->second.stop();
74 if ( get_timings().find(name) == get_timings().end() ) {
75 get_timings().emplace(std::string(name), Util::micro{0});
78 (get_timings().find(name))->second += time;
87 static auto report() -> std::string
89 std::string report{
"\n\nFunction Call Counts:\n"};
91 auto sortedCalls = sort_calls();
92 for (
auto const& [name, count] : sortedCalls ) {
93 report +=
"\t" + name +
": " + std::to_string(count) +
" calls\n";
96 report +=
"\n\nTimings:\n";
98 auto sortedTimings = sort_timings();
99 for (
auto const& [name, time] : sortedTimings ) {
100 auto percall = time / get_calls().at(name);
101 auto percallMilli = std::chrono::duration_cast<Util::milli>(percall);
102 percall -= percallMilli;
103 auto percallMicro = std::chrono::duration_cast<Util::micro>(percall);
106 auto seconds = std::chrono::duration_cast<Util::seconds>(copy);
108 auto milli = std::chrono::duration_cast<Util::milli>(copy);
110 auto micro = std::chrono::duration_cast<Util::micro>(copy);
112 report +=
"\t" + name +
":\n\t\tTotal Time: " + std::to_string(seconds.count()) +
113 "s " + std::to_string(milli.count()) +
"ms " +
114 std::to_string(micro.count()) +
"us\n";
115 report +=
"\t\tPer Call: " + std::to_string(percallMilli.count()) +
"ms " +
116 std::to_string(percallMicro.count()) +
"us\n";
128 FunctionTimer(FunctionTimer
const&) =
delete;
129 FunctionTimer(FunctionTimer&&) noexcept = delete;
130 auto operator=(FunctionTimer const&) -> FunctionTimer& = delete;
131 auto operator=(FunctionTimer&&) -> FunctionTimer& = delete;
132 explicit FunctionTimer(std::string_view name) noexcept : _name(name)
134 Perf::add_call(_name);
138 ~FunctionTimer() noexcept { Perf::stop(_name); }
141 std::string_view _name;
145 [[nodiscard]]
static auto get_calls() -> std::map<std::string, size_t, std::less<>>&
147 static std::map<std::string, size_t, std::less<>> calls;
151 [[nodiscard]]
static auto get_timings()
152 -> std::map<std::string, Util::micro, std::less<>>&
154 static std::map<std::string, Util::micro, std::less<>> timings;
158 [[nodiscard]]
static auto get_clocks()
159 -> std::map<std::string, Util::Clock<Util::micro>, std::less<>>&
161 static std::map<std::string, Util::Clock<Util::micro>, std::less<>> timings;
165 [[nodiscard]]
static auto sort_calls() -> std::vector<std::pair<std::string, size_t>>
167 const auto cmp = [](
auto const& left,
auto const& right) ->
bool {
168 return left.second > right.second;
171 std::vector<std::pair<std::string, size_t>> retVal;
172 for (
auto const& val : get_calls() ) {
173 retVal.emplace_back(val);
176 std::sort(retVal.begin(), retVal.end(), cmp);
181 [[nodiscard]]
static auto sort_timings()
182 -> std::vector<std::pair<std::string, Util::micro>>
184 const auto cmp = [](
auto const& left,
auto const& right) ->
bool {
185 return left.second > right.second;
188 std::vector<std::pair<std::string, Util::micro>> retVal;
189 for (
auto const& val : get_timings() ) {
190 retVal.emplace_back(val);
193 std::sort(retVal.begin(), retVal.end(), cmp);
Definition performance_testing.hpp:27
Definition performance_testing.hpp:20