32#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
34 m_setup_start_time = std::chrono::steady_clock::now();
41#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
43 m_setup_duration = std::chrono::steady_clock::now() - m_setup_start_time;
51 const std::chrono::duration<double>&
duration()
const {
52 return m_setup_duration;
57 bool m_enabled =
true;
58 std::chrono::steady_clock::time_point m_setup_start_time;
59 std::chrono::duration<double> m_setup_duration{0.0};
76#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
78 m_current_solve_start_time = std::chrono::steady_clock::now();
86#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
88 m_current_solve_duration =
89 std::chrono::steady_clock::now() - m_current_solve_start_time;
90 m_total_solve_duration += m_current_solve_duration;
93 m_average_solve_duration =
94 (m_num_solves - 1.0) / m_num_solves * m_average_solve_duration +
95 1.0 / m_num_solves * m_current_solve_duration;
109 return m_current_solve_duration;
116 return m_average_solve_duration;
123 return m_total_solve_duration;
128 bool m_enabled =
true;
129 std::chrono::steady_clock::time_point m_current_solve_start_time;
130 std::chrono::duration<double> m_current_solve_duration{0.0};
131 std::chrono::duration<double> m_total_solve_duration{0.0};
133 int m_num_solves = 0;
134 std::chrono::duration<double> m_average_solve_duration{0.0};
140 std::same_as<T, SetupTimeTracer> || std::same_as<T, SolveTimeTracer>;
145template <TimeTracer Tracer>
166 : m_tracer{rhs.m_tracer}, m_active{rhs.m_active} {
167 rhs.m_active =
false;
187 return m_tracer->current_duration();
192 bool m_active =
true;
201template <TimeTracer Tracer>
228 if (m_tracer !=
nullptr) {
245template <TimeTracer Tracer,
typename F>
246auto traced(Tracer& tracer,
const F& f) {
247 return [&tracer, &f]<
typename... Args>(Args&&... args) ->
decltype(
auto) {
248 ScopedTimeTracer scoped_tracer{tracer};
249 return f(std::forward<Args>(args)...);
256template <
typename ID>
257 requires std::is_enum_v<ID>
278template <
typename ID,
size_t N>
279consteval bool is_valid_time_trace(
281 if (N == 0 || entries[0].depth != 0) {
285 for (
size_t i = 1; i < N; ++i) {
287 if (std::to_underlying(entries[i].
id) <=
288 std::to_underlying(entries[i - 1].
id)) {
293 if (entries[i].depth < 1) {
300 if (entries[i].depth > entries[i - 1].depth + 1) {
312void tracer_id_is_not_in_time_trace();
319template <const auto& Entries>
320 requires(detail::is_valid_time_trace(Entries))
324 using ID =
decltype(Entries[0].id);
334 for (
size_t i = 0; i < Entries.size(); ++i) {
335 if (Entries[i].
id ==
id) {
341 detail::tracer_id_is_not_in_time_trace();
347 constexpr size_t value()
const {
return m_index; }
358template <TimeTracer Tracer, const auto& Entries>
359 requires(detail::is_valid_time_trace(Entries))
376 return m_tracers[index.
value()];
382 Tracer&
root() {
return m_tracers[0]; }
387 static constexpr std::span<const TimeTraceEntry<ID>, Entries.size()>
395 std::span<
const Tracer, Entries.size()>
tracers()
const {
return m_tracers; }
398 std::array<Tracer, Entries.size()> m_tracers;
Definition time_tracer.hpp:202
void next(Tracer &tracer)
Definition time_tracer.hpp:220
void stop()
Stops the active phase, if any.
Definition time_tracer.hpp:227
PhaseTimeTracer(Tracer &tracer) noexcept
Definition time_tracer.hpp:207
~PhaseTimeTracer()
Stops the active phase.
Definition time_tracer.hpp:212
Definition time_tracer.hpp:146
ScopedTimeTracer(Tracer &tracer) noexcept
Definition time_tracer.hpp:151
~ScopedTimeTracer()
Stops a tracer.
Definition time_tracer.hpp:156
ScopedTimeTracer(ScopedTimeTracer &&rhs) noexcept
Definition time_tracer.hpp:165
const std::chrono::duration< double > & current_duration() const
Definition time_tracer.hpp:186
void stop()
Definition time_tracer.hpp:176
Definition time_tracer.hpp:20
SetupTimeTracer(bool enabled)
Definition time_tracer.hpp:28
SetupTimeTracer()=default
Constructs an enabled tracer.
const std::chrono::duration< double > & duration() const
Definition time_tracer.hpp:51
void start()
Starts setup time measurement.
Definition time_tracer.hpp:31
void stop()
Stops setup time measurement.
Definition time_tracer.hpp:40
Definition time_tracer.hpp:64
void stop()
Definition time_tracer.hpp:85
const std::chrono::duration< double > & current_duration() const
Definition time_tracer.hpp:108
const std::chrono::duration< double > & total_duration() const
Definition time_tracer.hpp:122
const std::chrono::duration< double > & average_duration() const
Definition time_tracer.hpp:115
SolveTimeTracer(bool enabled)
Definition time_tracer.hpp:72
void start()
Starts solve time measurement.
Definition time_tracer.hpp:75
int num_solves() const
Definition time_tracer.hpp:103
SolveTimeTracer()=default
Constructs an enabled tracer.
Definition time_tracer.hpp:321
consteval TimeTracerIndex(ID id)
Definition time_tracer.hpp:333
constexpr size_t value() const
Definition time_tracer.hpp:347
decltype(Entries[0].id) ID
Time tracer ID enum type.
Definition time_tracer.hpp:324
Definition time_tracer.hpp:360
Tracer & root()
Definition time_tracer.hpp:382
TimeTracerTree(bool enabled)
Definition time_tracer.hpp:368
typename TimeTracerIndex< Entries >::ID ID
Time tracer ID enum type.
Definition time_tracer.hpp:363
static constexpr std::span< const TimeTraceEntry< ID >, Entries.size()> entries()
Definition time_tracer.hpp:388
Tracer & operator[](TimeTracerIndex< Entries > index)
Definition time_tracer.hpp:375
std::span< const Tracer, Entries.size()> tracers() const
Definition time_tracer.hpp:395
Time tracer concept.
Definition time_tracer.hpp:139
Definition time_tracer.hpp:258
std::string_view name
Name of measurement to show in diagnostics.
Definition time_tracer.hpp:263
ID id
Time tracer ID.
Definition time_tracer.hpp:260
int depth
Nesting depth in the time trace. The root has depth 0.
Definition time_tracer.hpp:266