-
Notifications
You must be signed in to change notification settings - Fork 1
/
noexcept_benchmark.h
155 lines (129 loc) · 5.18 KB
/
noexcept_benchmark.h
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
148
149
150
151
152
153
154
155
#ifndef noexcept_benchmark_h
#define noexcept_benchmark_h
/*
Copyright Niels Dekker, LKEB, Leiden University Medical Center
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <cassert>
#include <chrono>
#include <ctime>
#include <climits>
#include <exception>
#ifdef SPECIFY_NOEXCEPT
# if SPECIFY_NOEXCEPT == 0
# define OPTIONAL_EXCEPTION_SPECIFIER
# define LIB_NAME implicit_lib
# endif
# if SPECIFY_NOEXCEPT == 1
# define OPTIONAL_EXCEPTION_SPECIFIER noexcept
# define LIB_NAME noexcept_lib
# endif
#endif
#ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_ITERATIONS
# define NOEXCEPT_BENCHMARK_NUMBER_OF_ITERATIONS 10
#endif
#ifndef NOEXCEPT_BENCHMARK_THROW_EXCEPTION
# define NOEXCEPT_BENCHMARK_THROW_EXCEPTION 1
#endif
#ifdef NDEBUG
# ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_INLINE_FUNC_CALLS
# define NOEXCEPT_BENCHMARK_NUMBER_OF_INLINE_FUNC_CALLS 2147483647 // INT32_MAX (about two billion)
# endif
# ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_CLASS_MEMBER_FUNC_CALLS
# define NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_CLASS_MEMBER_FUNC_CALLS 200000000 // two hundred million
# endif
# ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_FUNC_CALLS
# define NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_FUNC_CALLS 200000000 // two hundred million
# endif
# ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_CATCHING_RECURSIVE_FUNC_CALLS
# define NOEXCEPT_BENCHMARK_NUMBER_OF_CATCHING_RECURSIVE_FUNC_CALLS 10000 // ten thousand
#endif
# ifndef NOEXCEPT_BENCHMARK_INC_AND_DEC_FUNC_CALLS
# define NOEXCEPT_BENCHMARK_INC_AND_DEC_FUNC_CALLS 2147483647 // INT32_MAX (about two billion)
# endif
# ifndef NOEXCEPT_BENCHMARK_STACK_UNWINDING_FUNC_CALLS
// Note: On Windows 10, x64, stack overflow occurred with N = 15000
# define NOEXCEPT_BENCHMARK_STACK_UNWINDING_FUNC_CALLS 10000 // ten thousand
# endif
# ifndef NOEXCEPT_BENCHMARK_STACK_UNWINDING_OBJECTS
// Note: On Windows 10, x64, stack overflow occurred with N = 1280000
# define NOEXCEPT_BENCHMARK_STACK_UNWINDING_OBJECTS 1000000 // a million
# endif
# ifndef NOEXCEPT_BENCHMARK_NUMBER_OF_FUNC_CALLS_EXPLICITLY_TERMINATE
# ifdef _MSC_VER
// This test appears to take much more time with MSVC (VS2017, VS2019), so do less iterations than with the other compilers.
# define NOEXCEPT_BENCHMARK_NUMBER_OF_FUNC_CALLS_EXPLICITLY_TERMINATE 200000000 // two hundred million
# else
# define NOEXCEPT_BENCHMARK_NUMBER_OF_FUNC_CALLS_EXPLICITLY_TERMINATE 2147483647 // INT32_MAX (about two billion)
# endif
# endif
# ifndef NOEXCEPT_BENCHMARK_INITIAL_VECTOR_SIZE
# define NOEXCEPT_BENCHMARK_INITIAL_VECTOR_SIZE 10000000 // ten million
# endif
#else
# define NOEXCEPT_BENCHMARK_NUMBER_OF_INLINE_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_CLASS_MEMBER_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_NUMBER_OF_EXPORTED_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_NUMBER_OF_CATCHING_RECURSIVE_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_INC_AND_DEC_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_STACK_UNWINDING_FUNC_CALLS 42
# define NOEXCEPT_BENCHMARK_STACK_UNWINDING_OBJECTS 42
# define NOEXCEPT_BENCHMARK_NUMBER_OF_FUNC_CALLS_EXPLICITLY_TERMINATE 42
# define NOEXCEPT_BENCHMARK_INITIAL_VECTOR_SIZE 42
#endif
namespace noexcept_benchmark
{
// Make `throw_exception_if(bool)` slightly more realistic, as C++ users
// typically throw an exception that is _derived_ from `std::exception`.
class exception_that_should_never_be_thrown : public std::exception
{
const char* what() const noexcept override
{
return "noexcept_benchmark exception, never ever intended to be thrown!";
}
};
inline void throw_exception_if(const bool do_throw_exception)
{
if (do_throw_exception)
{
assert(!"This function should only be called with do_throw_exception = false!");
#if NOEXCEPT_BENCHMARK_THROW_EXCEPTION
throw exception_that_should_never_be_thrown{};
#endif
}
}
inline bool get_false()
{
// The compiler may not assume that std::time returns non-zero,
// but in practie, it always does!
return std::time(nullptr) == 0;
}
template <typename T>
double profile_func_call(T func)
{
using namespace std::chrono;
const auto time_point1 = high_resolution_clock::now();
func();
const auto time_point2 = high_resolution_clock::now();
return duration_cast<duration<double>>(time_point2 - time_point1).count();
}
}
#define NOEXCEPT_BENCHMARK_EXCEPTION_SPECIFIER noexcept
#define NOEXCEPT_BENCHMARK_LIB_NAME noexcept_lib
#include "lib/lib.h"
#undef NOEXCEPT_BENCHMARK_LIB_NAME
#undef NOEXCEPT_BENCHMARK_EXCEPTION_SPECIFIER
#define NOEXCEPT_BENCHMARK_EXCEPTION_SPECIFIER
#define NOEXCEPT_BENCHMARK_LIB_NAME implicit_lib
#include "lib/lib.h"
#undef NOEXCEPT_BENCHMARK_LIB_NAME
#undef NOEXCEPT_BENCHMARK_EXCEPTION_SPECIFIER
#endif