uBench
Loading...
Searching...
No Matches
ubench.h
1#pragma once
2
3#include <iomanip>
4#include <ios>
5#include <memory>
6#include <string>
7#include <vector>
8
9namespace ubench {
10 using duration = long double;
11
12 using arg = size_t;
13 using args = std::vector<arg>;
14
15 template<typename T>
16 struct formatter;
17
18 template<>
19 struct formatter<arg> {
20 static std::string format(const arg v) {
21 return std::to_string(v);
22 }
23 };
24
25 template<>
26 struct formatter<duration> {
27 static std::string format(const duration v) {
28 std::stringstream ss;
29 ss << std::fixed << std::setprecision(2) << v;
30 return ss.str();
31 }
32 };
33
34 template<typename T>
35 std::string format(T v) {
36 return formatter<T>::format(v);
37 }
38
39 struct entry {
40 std::string_view name;
41 arg arg;
42 duration mean;
43 duration median;
44 duration stddev;
45 duration cv;
46 };
47
48 struct entry_size {
49 size_t name;
50 size_t mean;
51 size_t median;
52 size_t stddev;
53 size_t cv;
54
55 void adapt(const entry_size other) {
56 name = std::max(name, other.name);
57 mean = std::max(mean, other.mean);
58 median = std::max(median, other.median);
59 stddev = std::max(stddev, other.stddev);
60 cv = std::max(cv, other.cv);
61 }
62 };
63
64 struct formatted_entry {
65 std::string name;
66 std::string mean;
67 std::string median;
68 std::string stddev;
69 std::string cv;
70
71 formatted_entry(
72 std::string name,
73 std::string mean,
74 std::string median,
75 std::string stddev,
76 std::string cv)
77 : name(std::move(name)),
78 mean(std::move(mean)),
79 median(std::move(median)),
80 stddev(std::move(stddev)),
81 cv(std::move(cv)) {
82 }
83
84 explicit formatted_entry(const entry &e);
85
86 entry_size size() const;
87 void print(const entry_size &size) const;
88 };
89
90 using prepare_fn = void(*)(args &);
91 using target_fn = void(*)(arg);
92
93 struct options {
94 std::string name;
95 bool light_warmup = false;
96 target_fn target = nullptr;
97 prepare_fn prepare = nullptr;
98 size_t iteration = 10000;
99 size_t step = 20;
100 };
101
102 class benchmark;
103
104 std::vector<std::unique_ptr<options>> &get_options();
105
106 class benchmark {
107 options *_options;
108
109 void warmup_light(arg arg) const;
110 void warmup_heavy(arg arg) const;
111
112 public:
113 explicit benchmark(options *options) : _options(options) {
114 }
115
116 benchmark(const std::string &name, target_fn target);
117
124 benchmark prepare(const prepare_fn fn) const {
125 _options->prepare = fn;
126 return *this;
127 }
128
135 benchmark iteration(const size_t iteration) const {
136 _options->iteration = iteration;
137 return *this;
138 }
139
146 benchmark step(const size_t step) const {
147 _options->step = step;
148 return *this;
149 }
150
157 benchmark warmup(const bool light) const {
158 _options->light_warmup = light;
159 return *this;
160 }
161
169 [[nodiscard]]
170 duration operator()(arg arg, size_t iter) const;
171
178 [[nodiscard]]
179 entry operator()(arg arg) const;
180
186 void warm_up(arg arg) const;
187
193 void operator()(std::vector<entry> &entries) const;
194 };
195
201 std::vector<entry> run();
202
208 void print(const std::vector<entry> &entries);
209}
210
211#define UB_CONCAT_(a, b) a##b
212#define UB_CONCAT(a, b) UB_CONCAT_(a, b)
213#define BENCHMARK(fn) auto UB_CONCAT(__ubench_, __COUNTER__) = ubench::benchmark(#fn, fn)
Definition ubench.h:106
void operator()(std::vector< entry > &entries) const
duration operator()(arg arg, size_t iter) const
void warm_up(arg arg) const
benchmark step(const size_t step) const
Definition ubench.h:146
entry operator()(arg arg) const
benchmark warmup(const bool light) const
Definition ubench.h:157
benchmark iteration(const size_t iteration) const
Definition ubench.h:135
benchmark prepare(const prepare_fn fn) const
Definition ubench.h:124
Definition ubench.h:48
Definition ubench.h:39
Definition ubench.h:16
Definition ubench.h:93