22 requires std::is_same_v<T, std::chrono::nanoseconds> ||
23 std::is_same_v<T, std::chrono::microseconds> ||
24 std::is_same_v<T, std::chrono::milliseconds> ||
25 std::is_same_v<T, std::chrono::seconds> ||
26 std::is_same_v<T, std::chrono::minutes> ||
27 std::is_same_v<T, std::chrono::hours>;
31concept HasSize =
requires(
const T& t) { { t.size() } -> std::convertible_to<std::size_t>; };
33template <ChronoDuration T>
36 if constexpr (std::is_same_v<T, std::chrono::nanoseconds>) {
return "ns"; }
37 else if constexpr (std::is_same_v<T, std::chrono::microseconds>) {
return "μs"; }
38 else if constexpr (std::is_same_v<T, std::chrono::milliseconds>) {
return "ms"; }
39 else if constexpr (std::is_same_v<T, std::chrono::seconds>) {
return "s"; }
40 else if constexpr (std::is_same_v<T, std::chrono::minutes>) {
return "min"; }
41 else if constexpr (std::is_same_v<T, std::chrono::hours>) {
return "h"; }
42 else {
return "units"; }
46template <ChronoDuration Unit>
54 RuntimeProfile(std::vector<Unit>&& _raw_durations, std::vector<size_t>&& _sample_sizes) noexcept
61 template <ChronoDuration OtherUnit>
74 template <ChronoDuration UnitTo>
85template <ChronoDuration Unit = std::chrono::milliseconds,
typename Func,
typename... Args>
86requires std::invocable<Func, Args...>
89 const auto start = std::chrono::high_resolution_clock::now();
91 if constexpr (std::is_void_v<std::invoke_result_t<Func, Args...>>)
93 std::invoke(std::forward<Func>(func), std::forward<Args>(args)...);
97 [[maybe_unused]]
auto result = std::invoke(std::forward<Func>(func), std::forward<Args>(args)...);
100 const auto end = std::chrono::high_resolution_clock::now();
101 return std::chrono::duration_cast<Unit>(end - start);
104template <ChronoDuration Unit = std::chrono::milliseconds,
106 std::ranges::range Container,
108requires HasSize<std::ranges::range_value_t<Container>> &&
109 std::invocable<Func, const std::ranges::range_value_t<Container>&, Args...>
110[[nodiscard]]
auto profile_runtime(Func&& func,
const Container& samples, Args&&... args)
112 if (std::ranges::empty(samples))
114 throw std::invalid_argument(
"Cannot profile runtime with empty samples container");
117 std::vector<Unit> raw_durations;
118 std::vector<size_t> sample_sizes;
119 const auto num_samples = std::ranges::size(samples);
121 raw_durations.reserve(num_samples);
122 sample_sizes.reserve(num_samples);
125 auto invoke_func = [&func, ... captured_args = std::forward<Args>(args)](
const auto& sample)
mutable {
126 std::invoke(func, sample, std::forward<Args>(captured_args)...);
129 for (
const auto& sample : samples)
133 raw_durations.emplace_back(duration);
134 sample_sizes.emplace_back(sample.size());
140template <ChronoDuration Unit>
143 if (profile.raw_durations.empty())
return Unit::zero();
145 typename Unit::rep total = 0;
146 for (
const auto& duration : profile.raw_durations) { total += duration.count(); }
147 return Unit{total / profile.raw_durations.size()};
150template <ChronoDuration Unit>
153 typename Unit::rep total = 0;
154 for (
const auto& duration : profile.raw_durations) { total += duration.count(); }
Definition runtime_analyzer.hpp:20
Definition runtime_analyzer.hpp:31
Definition runtime_analyzer.hpp:16
constexpr std::string_view get_unit_symbol() noexcept
Definition runtime_analyzer.hpp:34
auto profile_runtime(Func &&func, const Container &samples, Args &&... args)
Definition runtime_analyzer.hpp:110
auto calculate_total(const RuntimeProfile< Unit > &profile) noexcept
Definition runtime_analyzer.hpp:151
auto calculate_average(const RuntimeProfile< Unit > &profile) noexcept
Definition runtime_analyzer.hpp:141
auto measure_duration(Func &&func, Args &&... args)
Definition runtime_analyzer.hpp:87
Definition runtime_analyzer.hpp:48
std::string unit_symbol
Definition runtime_analyzer.hpp:51
RuntimeProfile(const RuntimeProfile< OtherUnit > &other)
Definition runtime_analyzer.hpp:62
RuntimeProfile< UnitTo > convert_to() const
Definition runtime_analyzer.hpp:75
std::vector< Unit > raw_durations
Definition runtime_analyzer.hpp:49
RuntimeProfile(std::vector< Unit > &&_raw_durations, std::vector< size_t > &&_sample_sizes) noexcept
Definition runtime_analyzer.hpp:54
bool empty() const noexcept
Definition runtime_analyzer.hpp:82
std::size_t size() const noexcept
Definition runtime_analyzer.hpp:81
std::vector< size_t > sample_sizes
Definition runtime_analyzer.hpp:50