-
Notifications
You must be signed in to change notification settings - Fork 6
/
benchmark.cpp
201 lines (172 loc) · 7.51 KB
/
benchmark.cpp
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include <observer.h>
#include <functional>
#include <chrono>
#include <cstdio>
using namespace std;
using namespace std::chrono;
volatile int count_value = 0;
int iterations = 100000000;
volatile int increment = 1;
void increase_count( int value )
{
count_value += value;
}
struct increase_functor
{
int m_value = 0;
increase_functor( int value )
: m_value( value )
{}
void operator()( int )
{
count_value += m_value;
}
};
struct increase
{
int m_value = 0;
increase( int value )
: m_value( value )
{}
void increase_count( int )
{
count_value += m_value;
}
};
int main( int /* argc */, char * /* argv */[] )
{
pg::connection_owner owner;
std::function< void( int ) > increase_count_std_function = [&]( int value ){ count_value += value; };
auto increase_count_lambda_function = [&]( int value ){ count_value += value; };
auto increase_count_functor = increase_functor( increment );
auto increase_member_function = increase( increment );
// Get the baseline
count_value = 0;
const auto baseline_start_free_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
increase_count( increment );
increase_count( increment );
}
const auto baseline_stop_free_function = std::chrono::steady_clock::now();
count_value = 0;
const auto baseline_start_std_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
increase_count_std_function( increment );
increase_count_std_function( increment );
}
const auto baseline_stop_std_function = std::chrono::steady_clock::now();
count_value = 0;
const auto baseline_start_lambda = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
increase_count_lambda_function( increment );
increase_count_lambda_function( increment );
}
const auto baseline_stop_lambda = std::chrono::steady_clock::now();
count_value = 0;
const auto baseline_start_functor = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
increase_count_functor( increment );
increase_count_functor( increment );
}
const auto baseline_stop_functor = std::chrono::steady_clock::now();
count_value = 0;
const auto baseline_start_member_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
increase_member_function.increase_count( increment );
increase_member_function.increase_count( increment );
}
const auto baseline_stop_member_function = std::chrono::steady_clock::now();
// With observers
count_value = 0;
pg::subject< int > subject_free_function;
owner.connect( subject_free_function, increase_count );
owner.connect( subject_free_function, increase_count );
const auto start_free_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
subject_free_function.notify( increment );
}
const auto stop_free_function = std::chrono::steady_clock::now();
count_value = 0;
pg::subject< int > subject_std_function;
owner.connect( subject_std_function, increase_count_std_function );
owner.connect( subject_std_function, increase_count_std_function );
const auto start_std_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
subject_std_function.notify( increment );
}
const auto stop_std_function = std::chrono::steady_clock::now();
count_value = 0;
pg::subject< int > subject_lambda;
owner.connect( subject_lambda, [&]( int value ){ count_value += value; } );
owner.connect( subject_lambda, [&]( int value ){ count_value += value; } );
const auto start_lambda = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
subject_lambda.notify( increment );
}
const auto stop_lambda = std::chrono::steady_clock::now();
count_value = 0;
pg::subject< int > subject_functor;
owner.connect( subject_functor, increase_count_functor );
owner.connect( subject_functor, increase_count_functor );
const auto start_functor = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
subject_functor.notify( increment );
}
const auto stop_functor = std::chrono::steady_clock::now();
count_value = 0;
pg::subject< int > subject_member_function;
owner.connect( subject_member_function, &increase_member_function, &increase::increase_count );
owner.connect( subject_member_function, &increase_member_function, &increase::increase_count );
const auto start_member_function = std::chrono::steady_clock::now();
for( int i = 0 ; i < iterations ; ++i )
{
subject_member_function.notify( increment );
}
const auto stop_member_function = std::chrono::steady_clock::now();
struct result
{
using time_point = std::chrono::steady_clock::time_point;
using time = std::chrono::duration< float, std::micro >;
const float m_base_time;
const float m_time;
const float m_difference;
result( const time_point & base_start,
const time_point & base_stop,
const time_point & start,
const time_point & stop )
: m_base_time( time( base_stop - base_start ).count() )
, m_time( time( stop - start ).count() )
, m_difference( time( stop - start ).count() / time( base_stop - base_start ).count() )
{}
};
auto free_function_result = result( baseline_start_free_function, baseline_stop_free_function, start_free_function, stop_free_function );
auto std_function_result = result( baseline_start_std_function, baseline_stop_std_function, start_std_function, stop_std_function );
auto lambda_result = result( baseline_start_lambda, baseline_stop_lambda, start_lambda, stop_lambda );
auto functor_result = result( baseline_start_functor, baseline_stop_functor, start_functor, stop_functor );
auto member_function_result = result( baseline_start_member_function, baseline_stop_member_function, start_member_function, stop_member_function );
printf(
"|--------------------------------------------------------|\n"
"| | baseline | observer | difference |\n"
"|--------------------------------------------------------|\n"
"| free function | %10.2f | %10.2f | %9.2fx |\n"
"| std::function | %10.2f | %10.2f | %9.2fx |\n"
"| lambda | %10.2f | %10.2f | %9.2fx |\n"
"| functor | %10.2f | %10.2f | %9.2fx |\n"
"| member function | %10.2f | %10.2f | %9.2fx |\n"
"|--------------------------------------------------------|\n",
free_function_result.m_base_time, free_function_result.m_time, free_function_result.m_difference,
std_function_result.m_base_time, std_function_result.m_time, std_function_result.m_difference,
lambda_result.m_base_time, lambda_result.m_time, lambda_result.m_difference,
functor_result.m_base_time, functor_result.m_time, functor_result.m_difference,
member_function_result.m_base_time, member_function_result.m_time, member_function_result.m_difference );
return 0;
}