1 /************************************************************************************
2 * *
3 * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
4 * *
5 * This file is part of RTTR (Run Time Type Reflection) *
6 * License: MIT License *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining *
9 * a copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
24 * SOFTWARE. *
25 * *
26 *************************************************************************************/
27
28 #include <rttr/type>
29 #include <rttr/registration>
30
31 #include <nonius/nonius.h++>
32 #include <nonius/html_group_reporter.h>
33
34 #include <locale>
35
36 /////////////////////////////////////////////////////////////////////////////////////////
37 /////////////////////////////////////////////////////////////////////////////////////////
38 /////////////////////////////////////////////////////////////////////////////////////////
39
setup_integer()40 static int setup_integer()
41 {
42 return 12345;
43 }
44
45 /////////////////////////////////////////////////////////////////////////////////////////
46
setup_float()47 static float setup_float()
48 {
49 return 123.12345f;
50 }
51
52 /////////////////////////////////////////////////////////////////////////////////////////
53
setup_double()54 static double setup_double()
55 {
56 return 123456.123456;
57 }
58
59 /////////////////////////////////////////////////////////////////////////////////////////
60
setup_bool()61 static bool setup_bool()
62 {
63 return true;
64 }
65
66 /////////////////////////////////////////////////////////////////////////////////////////
67
setup_string_integer()68 static std::string setup_string_integer()
69 {
70 return std::string("12345");
71 }
72
73 /////////////////////////////////////////////////////////////////////////////////////////
74
setup_string_float()75 static std::string setup_string_float()
76 {
77 return std::string("123.12345");
78 }
79
80 /////////////////////////////////////////////////////////////////////////////////////////
81
setup_string_double()82 static std::string setup_string_double()
83 {
84 return std::string("123456.123456");
85 }
86
87 /////////////////////////////////////////////////////////////////////////////////////////
88
setup_string_bool()89 static std::string setup_string_bool()
90 {
91 return std::string("1");
92 }
93
94
95 /////////////////////////////////////////////////////////////////////////////////////////
96 /////////////////////////////////////////////////////////////////////////////////////////
97 /////////////////////////////////////////////////////////////////////////////////////////
98
bench_native_int_to_string()99 nonius::benchmark bench_native_int_to_string()
100 {
101 return nonius::benchmark("native", [](nonius::chronometer meter)
102 {
103 int var = setup_integer();
104 std::string result;
105 meter.measure([&]()
106 {
107 result = std::to_string(var);
108 });
109 });
110 }
111
112 /////////////////////////////////////////////////////////////////////////////////////////
113
bench_variant_int_to_string()114 nonius::benchmark bench_variant_int_to_string()
115 {
116 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
117 {
118 rttr::variant var = setup_integer();
119 std::string result;
120 meter.measure([&]()
121 {
122 result = var.to_string();
123 });
124 });
125 }
126
127 /////////////////////////////////////////////////////////////////////////////////////////
128 /////////////////////////////////////////////////////////////////////////////////////////
129
bench_native_string_to_int()130 nonius::benchmark bench_native_string_to_int()
131 {
132 return nonius::benchmark("native", [](nonius::chronometer meter)
133 {
134 std::string number_string = setup_string_integer();
135 int result = 0;
136 meter.measure([&]()
137 {
138 std::size_t pos = 0;
139 result = std::stoi(number_string, &pos);
140 });
141 });
142 }
143
144 /////////////////////////////////////////////////////////////////////////////////////////
145
bench_variant_string_to_int()146 nonius::benchmark bench_variant_string_to_int()
147 {
148 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
149 {
150 rttr::variant var = setup_string_integer();
151 int result = 0;
152 meter.measure([&]()
153 {
154 result = var.to_int();
155 });
156 });
157 }
158
159 /////////////////////////////////////////////////////////////////////////////////////////
160 /////////////////////////////////////////////////////////////////////////////////////////
161 /////////////////////////////////////////////////////////////////////////////////////////
162
bench_native_float_to_string()163 nonius::benchmark bench_native_float_to_string()
164 {
165 return nonius::benchmark("native", [](nonius::chronometer meter)
166 {
167 float var = setup_float();
168 std::string result;
169 meter.measure([&]()
170 {
171 result = std::to_string(var);
172 });
173 });
174 }
175
176 /////////////////////////////////////////////////////////////////////////////////////////
177
bench_variant_float_to_string()178 nonius::benchmark bench_variant_float_to_string()
179 {
180 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
181 {
182 rttr::variant var = setup_float();
183 std::string result;
184 meter.measure([&]()
185 {
186 result = var.to_string();
187 });
188 });
189 }
190
191 /////////////////////////////////////////////////////////////////////////////////////////
192 /////////////////////////////////////////////////////////////////////////////////////////
193
bench_native_string_to_float()194 nonius::benchmark bench_native_string_to_float()
195 {
196 return nonius::benchmark("native", [](nonius::chronometer meter)
197 {
198 std::string number_string = setup_string_float();
199 float result;
200 meter.measure([&]()
201 {
202 std::size_t pos = 0;
203 result = std::stof(number_string, &pos);
204 });
205 });
206 }
207
208 /////////////////////////////////////////////////////////////////////////////////////////
209
bench_variant_string_to_float()210 nonius::benchmark bench_variant_string_to_float()
211 {
212 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
213 {
214 rttr::variant var = setup_string_float();
215 float result = 0.0f;
216 meter.measure([&]()
217 {
218 result = var.to_float();
219 });
220 });
221 }
222
223 /////////////////////////////////////////////////////////////////////////////////////////
224 /////////////////////////////////////////////////////////////////////////////////////////
225 /////////////////////////////////////////////////////////////////////////////////////////
226
bench_native_double_to_string()227 nonius::benchmark bench_native_double_to_string()
228 {
229 return nonius::benchmark("native", [](nonius::chronometer meter)
230 {
231 double var = setup_double();
232 std::string result;
233 meter.measure([&]()
234 {
235 result = std::to_string(var);
236 });
237 });
238 }
239
240 /////////////////////////////////////////////////////////////////////////////////////////
241
bench_variant_double_to_string()242 nonius::benchmark bench_variant_double_to_string()
243 {
244 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
245 {
246 rttr::variant var = setup_double();
247 std::string result;
248 meter.measure([&]()
249 {
250 result = var.to_string();
251 });
252 });
253 }
254
255 /////////////////////////////////////////////////////////////////////////////////////////
256 /////////////////////////////////////////////////////////////////////////////////////////
257
bench_native_string_to_double()258 nonius::benchmark bench_native_string_to_double()
259 {
260 return nonius::benchmark("native", [](nonius::chronometer meter)
261 {
262 std::string number_string = setup_string_double();
263 double result;
264 meter.measure([&]()
265 {
266 std::size_t pos = 0;
267 result = std::stod(number_string, &pos);
268 });
269 });
270 }
271
272 /////////////////////////////////////////////////////////////////////////////////////////
273
bench_variant_string_to_double()274 nonius::benchmark bench_variant_string_to_double()
275 {
276 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
277 {
278 rttr::variant var = setup_string_double();
279 double result = 0.0;
280 meter.measure([&]()
281 {
282 result = var.to_double();
283 });
284 });
285 }
286
287 /////////////////////////////////////////////////////////////////////////////////////////
288 /////////////////////////////////////////////////////////////////////////////////////////
289 /////////////////////////////////////////////////////////////////////////////////////////
290
bench_native_bool_to_string()291 nonius::benchmark bench_native_bool_to_string()
292 {
293 return nonius::benchmark("native", [](nonius::chronometer meter)
294 {
295 bool value = setup_bool();
296 std::string result;
297 meter.measure([&]()
298 {
299 result = value ? std::string("true") : std::string("false");
300 });
301 });
302 }
303
304 /////////////////////////////////////////////////////////////////////////////////////////
305
bench_variant_bool_to_string()306 nonius::benchmark bench_variant_bool_to_string()
307 {
308 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
309 {
310 rttr::variant var = setup_bool();
311 std::string result;
312 meter.measure([&]()
313 {
314 result = var.to_string();
315 });
316 });
317 }
318
319 /////////////////////////////////////////////////////////////////////////////////////////
320 /////////////////////////////////////////////////////////////////////////////////////////
321
string_to_bool(std::string text)322 static bool string_to_bool(std::string text)
323 {
324 std::transform(text.cbegin(), text.cend(), text.begin(), ::tolower);
325 text.erase( std::remove_if( text.begin(), text.end(), []( char ch ) { return std::isspace<char>( ch, std::locale::classic() ); } ), text.end() );
326
327 return !(text == "false" || text == "0" || text.empty());
328 }
329
330 /////////////////////////////////////////////////////////////////////////////////////////
331
bench_native_string_to_bool()332 nonius::benchmark bench_native_string_to_bool()
333 {
334 return nonius::benchmark("native", [](nonius::chronometer meter)
335 {
336 std::string bool_string = setup_string_bool();
337 bool result = false;
338 meter.measure([&]()
339 {
340 result = string_to_bool(bool_string);
341 });
342 });
343 }
344
345 /////////////////////////////////////////////////////////////////////////////////////////
346
bench_variant_string_to_bool()347 nonius::benchmark bench_variant_string_to_bool()
348 {
349 return nonius::benchmark("rttr::variant", [](nonius::chronometer meter)
350 {
351 rttr::variant var = setup_string_bool();
352 bool result = false;
353 meter.measure([&]()
354 {
355 result = var.to_bool();
356 });
357 });
358 }
359
360 /////////////////////////////////////////////////////////////////////////////////////////
361 /////////////////////////////////////////////////////////////////////////////////////////
362 /////////////////////////////////////////////////////////////////////////////////////////
363
bench_variant_conversion()364 void bench_variant_conversion()
365 {
366 nonius::configuration cfg;
367 cfg.title = "rttr::variant conversion";
368
369 nonius::html_group_reporter reporter;
370 reporter.set_output_file("benchmark_variant_conversion.html");
371
372 //////////////////////////////////
373
374 reporter.set_current_group_name("int to string", "Converts an integer number to a <code>std::string</code>:<br><pre>rttr::variant var = 12345;\nvar.to_string();</pre>");
375
376 nonius::benchmark benchmarks_group_1[] = { bench_native_int_to_string(),
377 bench_variant_int_to_string()
378 };
379
380 nonius::go(cfg, std::begin(benchmarks_group_1), std::end(benchmarks_group_1), reporter);
381
382 //////////////////////////////////
383
384 reporter.set_current_group_name("string to int", "Converts a <code>std::string</code> to an integer:<br><pre>rttr::variant var = std::string(\"12345\");\nvar.to_int()</pre>");
385
386 nonius::benchmark benchmarks_group_2[] = { bench_native_string_to_int(),
387 bench_variant_string_to_int()
388 };
389
390 nonius::go(cfg, std::begin(benchmarks_group_2), std::end(benchmarks_group_2), reporter);
391
392 //////////////////////////////////
393
394 reporter.set_current_group_name("float to string", "Converts a floating point number to a <code>std::string</code>:<br><pre>rttr::variant var = 123.12345f;\nvar.to_string();</pre>");
395
396 nonius::benchmark benchmarks_group_3[] = { bench_native_string_to_float(),
397 bench_variant_string_to_float()
398 };
399
400 nonius::go(cfg, std::begin(benchmarks_group_3), std::end(benchmarks_group_3), reporter);
401
402 //////////////////////////////////
403
404 reporter.set_current_group_name("string to float", "Converts a <code>std::string</code> to a floating point number:<br><pre>rttr::variant var = std::string(\"123.12345\");\nvar.to_float().");
405
406 nonius::benchmark benchmarks_group_4[] = { bench_native_float_to_string(),
407 bench_variant_float_to_string()
408 };
409
410 nonius::go(cfg, std::begin(benchmarks_group_4), std::end(benchmarks_group_4), reporter);
411
412 //////////////////////////////////
413
414 reporter.set_current_group_name("double to string", "Converts a double number to a <code>std::string</code>:<br><pre>rttr::variant var = 123456.123456;\nvar.to_string();</pre>");
415
416 nonius::benchmark benchmarks_group_5[] = { bench_native_string_to_double(),
417 bench_variant_string_to_double()
418 };
419
420 nonius::go(cfg, std::begin(benchmarks_group_5), std::end(benchmarks_group_5), reporter);
421
422 //////////////////////////////////
423
424 reporter.set_current_group_name("string to double", "Converts a <code>std::string</code> to a double number:<br><pre>rttr::variant var = std::string(\"123456.123456\");\nvar.to_double();</pre>");
425
426 nonius::benchmark benchmarks_group_6[] = { bench_native_double_to_string(),
427 bench_variant_double_to_string()
428 };
429
430 nonius::go(cfg, std::begin(benchmarks_group_6), std::end(benchmarks_group_6), reporter);
431
432 //////////////////////////////////
433
434 reporter.set_current_group_name("bool to string", "Converts a bool number to a <code>std::string</code>:<br><pre>rttr::variant var = 123456.123456;\nvar.to_string();</pre>");
435
436 nonius::benchmark benchmarks_group_7[] = { bench_native_string_to_bool(),
437 bench_variant_string_to_bool()
438 };
439
440 nonius::go(cfg, std::begin(benchmarks_group_7), std::end(benchmarks_group_7), reporter);
441
442 //////////////////////////////////
443
444 reporter.set_current_group_name("string to bool", "Converts a <code>std::string</code> to a bool number:<br><pre>rttr::variant var = std::string(\"123456.123456\");\nvar.to_bool();</pre>");
445
446 nonius::benchmark benchmarks_group_8[] = { bench_native_bool_to_string(),
447 bench_variant_bool_to_string()
448 };
449
450 nonius::go(cfg, std::begin(benchmarks_group_8), std::end(benchmarks_group_8), reporter);
451
452 //////////////////////////////////
453
454 reporter.generate_report();
455 }
456
457 /////////////////////////////////////////////////////////////////////////////////////////
458