forked from NoAvailableAlias/signal-slot-benchmarks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
benchmark_utility.hpp
147 lines (123 loc) · 3.99 KB
/
benchmark_utility.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#pragma once
#include <algorithm>
#include <iostream>
#include <cassert>
#include <numeric>
#include <chrono>
#include <future>
#include <memory>
#include <random>
#include <vector>
#include <tuple>
#include <map>
#ifdef _WIN32
#define NOINLINE(s) __declspec(noinline) s
#elif __unix__
#define NOINLINE(s) __attribute__ ((noinline)) s
#else
#define NOINLINE(s) s
#endif
typedef std::minstd_rand Rng;
// Time units used internally in the benchmarks
typedef std::chrono::nanoseconds Timer_u;
typedef std::chrono::milliseconds Limit_u;
typedef std::chrono::duration<double, std::milli> Delta_u;
// Used for gathering raw lib benchmark scores
typedef std::pair<std::size_t, double> BenchmarkRawResult;
typedef std::map<const char*, std::vector<BenchmarkRawResult>> BenchmarkMethodResults;
typedef std::map<const char*, BenchmarkMethodResults> BenchmarkClassResults;
// Used for post-benchmark processing and report output
typedef std::map<const char*, double> ReportMethodResults;
typedef std::map<const char*, ReportMethodResults> ReportClassResults;
typedef std::pair<const char*, ReportMethodResults*> ReportOrderedResult;
typedef std::map<double, ReportOrderedResult> ReportOrderedResults;
// Used for the initialization of jlsignal
constexpr const std::size_t C_JLSIGNAL_MAX = 256;
// Constants used to map to a particular benchmark method
constexpr const char* C_CONSTRUCTION = "[constr]";
constexpr const char* C_DESTRUCTION = "[destr]";
constexpr const char* C_CONNECTION = "conn";
constexpr const char* C_DISCONNECT = "disconn";
constexpr const char* C_RECONNECT = "reconn";
constexpr const char* C_EMISSION = "emit";
constexpr const char* C_COMBINED = "all";
constexpr const char* C_THREADED = "threaded";
//------------------------------------------------------------------------------
typedef std::shared_ptr<void> SlotScope;
template <typename Deleter>
SlotScope make_slot_scope(Deleter&& deleter)
{
return SlotScope(nullptr, deleter);
}
//------------------------------------------------------------------------------
template <unsigned int N>
struct tee_stream
{
template <typename ...Args, typename T>
static std::tuple<Args...>& print(std::tuple<Args...>& t, T&& x)
{
std::get<sizeof...(Args) - N>(t) << x;
tee_stream<N - 1>::print(t, std::forward<T>(x));
return t;
}
};
template <>
struct tee_stream<0>
{
template <typename ...Args, typename T>
static std::tuple<Args...>& print(std::tuple<Args...>& t, T&&)
{
return t;
}
};
template <typename ...Args, typename T>
std::tuple<Args...>& operator<< (std::tuple<Args...>& t, T&& x)
{
return tee_stream<sizeof...(Args)>::print(t, std::forward<T>(x));
}
template <typename ...Args, typename T>
std::tuple<Args...>& operator<< (std::tuple<Args...>&& t, T&& x)
{
return tee_stream<sizeof...(Args)>::print(t, std::forward<T>(x));
}
//------------------------------------------------------------------------------
template <typename Iterator> struct RangeHelper
{
Iterator lhs;
Iterator rhs;
Iterator cbegin() const { return lhs; }
Iterator begin() const { return lhs; }
Iterator cend() const { return rhs; }
Iterator end() const { return rhs; }
};
template <typename Iterator>
static RangeHelper<Iterator> Range(Iterator lhs,
Iterator rhs)
{
return { lhs, rhs };
}
//------------------------------------------------------------------------------
class ChronoTimer
{
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
public:
ChronoTimer() : m_start(std::chrono::high_resolution_clock::now())
{
}
void reset()
{
new (this) ChronoTimer;
}
template <typename T>
std::size_t count() const
{
return std::chrono::duration_cast<T>
(std::chrono::high_resolution_clock::now() - m_start).count();
}
};
//------------------------------------------------------------------------------
struct IncrementFill
{
std::size_t i = 0;
std::size_t operator()() { return i++; }
};