FE
0.13.1
Header-only C++ frontend library
Toggle main menu visibility
Loading...
Searching...
No Matches
profile.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <chrono>
4
#include <cstdint>
5
6
#include <limits>
7
#include <ostream>
8
#include <string>
9
#include <string_view>
10
#include <utility>
11
#include <vector>
12
13
namespace
fe
{
14
15
/// Records wall-clock timings for (possibly nested) named Profiler::Span%s and reports them in various formats.
16
/// Span%s nest like a stack, so each one remembers its parent.
17
/// From these Span%s the Profiler can derive
18
/// - a flat Profiler::summary aggregated by name,
19
/// - a hierarchical Profiler::tree that shows the runtimes in context, and
20
/// - a [Chrome Trace Event](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU)
21
/// JSON dump (Profiler::chrome_trace) that can be loaded into `chrome://tracing`, Perfetto, or speedscope.
22
/// @see Profiler::start, Profiler::stop
23
class
Profiler
{
24
public
:
25
using
Clock
= std::chrono::steady_clock;
26
using
Duration
= Clock::duration;
27
28
static
constexpr
size_t
No_Parent
= std::numeric_limits<size_t>::max();
29
30
/// A single run.
31
struct
Span
{
32
std::string
name
;
33
Clock::time_point
start
;
34
Clock::time_point
stop
;
35
size_t
depth
;
///< Nesting level; a root Span has depth 0.
36
size_t
parent
;
///< Index of the enclosing Span in Profiler::spans, or Profiler::No_Parent for a root.
37
std::vector<std::pair<std::string, uint64_t>>
counters
;
///< Custom counters (insertion order).
38
39
Duration
elapsed
()
const
{
return
stop
-
start
; }
40
};
41
42
/// @name Getters
43
///@{
44
bool
empty
()
const
{
return
spans_.empty(); }
45
const
auto
&
spans
()
const
{
return
spans_; }
46
///@}
47
48
/// @name Recording
49
/// Bracket a run with Profiler::start / Profiler::stop; the calls must nest like a stack.
50
///@{
51
/// Marks the start of a run named @p name.
52
void
start
(std::string_view name) {
53
auto
parent = stack_.empty() ?
No_Parent
: stack_.back();
54
stack_.emplace_back(spans_.size());
55
spans_.emplace_back(std::string(name), Clock::now(), Clock::time_point{}, stack_.size() - 1, parent);
56
}
57
58
/// Marks the end of the most recently started run; no-op if no Span is running.
59
void
stop
() {
60
if
(stack_.empty())
return
;
61
auto
id
= stack_.back();
62
stack_.pop_back();
63
spans_[id].stop = Clock::now();
64
}
65
66
/// Adds @p n to counter @p key of the currently running Span; no-op if no Span is running or @p n is `0`.
67
void
count
(std::string_view key, uint64_t n = 1) {
68
if
(stack_.empty() || n == 0)
return
;
69
auto
& counters = spans_[stack_.back()].counters;
70
for
(
auto
& [k, v] : counters) {
71
if
(k == key) {
72
v += n;
73
return
;
74
}
75
}
76
counters.emplace_back(std::string(key), n);
77
}
78
///@}
79
80
/// @name Reporting
81
///@{
82
/// Prints a flat table aggregated by name, sorted by total time, descending.
83
void
summary
(std::ostream&)
const
;
84
/// Prints the Span%s as an indented tree, preserving the order in which they ran.
85
void
tree
(std::ostream&)
const
;
86
/// Dumps all Span%s as Chrome Trace Event Format JSON.
87
void
chrome_trace
(std::ostream&)
const
;
88
///@}
89
90
private
:
91
/// Per-Span time spent in *direct* children; `self = elapsed - children`.
92
std::vector<Duration> children_durations()
const
;
93
94
std::vector<size_t> stack_;
95
std::vector<Span> spans_;
96
};
97
98
}
// namespace fe
fe::Profiler
Records wall-clock timings for (possibly nested) named Profiler::Spans and reports them in various fo...
Definition
profile.h:23
fe::Profiler::tree
void tree(std::ostream &) const
Prints the Spans as an indented tree, preserving the order in which they ran.
fe::Profiler::spans
const auto & spans() const
Definition
profile.h:45
fe::Profiler::count
void count(std::string_view key, uint64_t n=1)
Adds n to counter key of the currently running Span; no-op if no Span is running or n is 0.
Definition
profile.h:67
fe::Profiler::Duration
Clock::duration Duration
Definition
profile.h:26
fe::Profiler::empty
bool empty() const
Definition
profile.h:44
fe::Profiler::start
void start(std::string_view name)
Definition
profile.h:52
fe::Profiler::stop
void stop()
Marks the end of the most recently started run; no-op if no Span is running.
Definition
profile.h:59
fe::Profiler::chrome_trace
void chrome_trace(std::ostream &) const
Dumps all Spans as Chrome Trace Event Format JSON.
fe::Profiler::No_Parent
static constexpr size_t No_Parent
Definition
profile.h:28
fe::Profiler::Clock
std::chrono::steady_clock Clock
Definition
profile.h:25
fe::Profiler::summary
void summary(std::ostream &) const
fe
Definition
algo.h:17
fe::Profiler::Span
A single run.
Definition
profile.h:31
fe::Profiler::Span::start
Clock::time_point start
Definition
profile.h:33
fe::Profiler::Span::depth
size_t depth
Nesting level; a root Span has depth 0.
Definition
profile.h:35
fe::Profiler::Span::elapsed
Duration elapsed() const
Definition
profile.h:39
fe::Profiler::Span::parent
size_t parent
Index of the enclosing Span in Profiler::spans, or Profiler::No_Parent for a root.
Definition
profile.h:36
fe::Profiler::Span::counters
std::vector< std::pair< std::string, uint64_t > > counters
Custom counters (insertion order).
Definition
profile.h:37
fe::Profiler::Span::name
std::string name
Definition
profile.h:32
fe::Profiler::Span::stop
Clock::time_point stop
Definition
profile.h:34
fe
profile.h
Generated by
1.18.0