Gamp v0.0.7-67-g7798ac4
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
test_stringfmt_perf_int.cpp
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * ***
6 *
7 * SPDX-License-Identifier: MIT
8 *
9 * This Source Code Form is subject to the terms of the MIT License
10 * If a copy of the MIT was not distributed with this
11 * file, You can obtain one at https://opensource.org/license/mit/.
12 *
13 */
14#include <sys/types.h>
15#include <cassert>
16#include <cstdio>
17#include <cstring>
18#include <iomanip>
19#include <string_view>
20
21#include <jau/basic_types.hpp>
22#include <jau/cpp_lang_util.hpp>
23#include <jau/cpp_pragma.hpp>
24#include <jau/float_types.hpp>
25#include <jau/int_types.hpp>
26#include <jau/string_cfmt.hpp>
28#include <jau/string_util.hpp>
29#include <jau/test/catch2_ext.hpp>
30#include <jau/type_concepts.hpp>
32
33#ifdef HAS_STD_FORMAT
34 #include <format>
35#endif
36
37using namespace std::literals;
38
39using namespace jau::float_literals;
40
41using namespace jau::int_literals;
42
43TEST_CASE("jau_cfmt_benchmark_int0", "[benchmark][jau][std::string][format_int]") {
44 const size_t loops = 1000; // catch_auto_run ? 1000 : 1000;
45 WARN("Benchmark with " + std::to_string(loops) + " loops");
46 CHECK(true);
47
48 static constexpr const char *format_check_exp = "format_check: 3";
49 BENCHMARK("fmt1.32 format rsrved bench") {
50 int i1 = 3;
51
52 volatile size_t res = 0;
53 for( size_t i = 0; i < loops; ++i ) {
54 std::string s = jau::format_string("format_check: %d", i1);
55 REQUIRE(format_check_exp == s);
56 res = res + s.size();
57 }
58 return res;
59 };
60 BENCHMARK("fmtX.32 snprintf rsrved bench") {
61 int i1 = 3;
62
63 volatile size_t res = 0;
64 for( size_t i = 0; i < loops; ++i ) {
65 std::string s;
66 const size_t bsz = jau::cfmt::default_string_capacity + 1; // including EOS
67 s.reserve(bsz); // incl. EOS
68 s.resize(bsz - 1); // excl. EOS
69 size_t nchars = std::snprintf(&s[0], bsz, "format_check: %d", i1);
70 if( nchars < bsz ) {
71 s.resize(nchars);
72 }
73 REQUIRE(format_check_exp == s);
74 res = res + nchars;
75 }
76 return res;
77 };
78}
79
80TEST_CASE("jau_cfmt_benchmark_int1", "[benchmark][jau][std::string][format_int]") {
81 const size_t loops = 1000; // catch_auto_run ? 1000 : 1000;
82 WARN("Benchmark with " + std::to_string(loops) + " loops");
83 CHECK(true);
84
85 static constexpr const char *format_check_exp = "format_check: 003";
86 BENCHMARK("fmt1.32 format rsrved bench") {
87 int i1 = 3;
88
89 volatile size_t res = 0;
90 for( size_t i = 0; i < loops; ++i ) {
91 std::string s = jau::format_string("format_check: %03d", i1);
92 REQUIRE(format_check_exp == s);
93 res = res + s.size();
94 }
95 return res;
96 };
97 BENCHMARK("fmtX.32 snprintf rsrved bench") {
98 int i1 = 3;
99
100 volatile size_t res = 0;
101 for( size_t i = 0; i < loops; ++i ) {
102 std::string s;
103 const size_t bsz = jau::cfmt::default_string_capacity + 1; // including EOS
104 s.reserve(bsz); // incl. EOS
105 s.resize(bsz - 1); // excl. EOS
106 size_t nchars = std::snprintf(&s[0], bsz, "format_check: %03d", i1);
107 if( nchars < bsz ) {
108 s.resize(nchars);
109 }
110 REQUIRE(format_check_exp == s);
111 res = res + nchars;
112 }
113 return res;
114 };
115}
116
117/// Execute with `test_stringfmt_perf --perf-analysis`
118TEST_CASE("jau_cfmt_benchmark_int2", "[benchmark][jau][std::string][format_int]") {
119 const size_t loops = 1000; // catch_auto_run ? 1000 : 1000;
120 WARN("Benchmark with " + std::to_string(loops) + " loops");
121 CHECK(true);
122
123 static constexpr const std::string_view format_check_exp1 = "format_check: -1, 2";
124 int i1=-1;
125 size_t i2=2;
126
127 BENCHMARK("fmt1.130 formatR rsrved bench") {
128 volatile size_t res = 0;
129 for( size_t i = 0; i < loops; ++i ) {
130 std::string s;
132
133 jau::cfmt::formatR(s, "format_check: %d, %zu", i1, i2);
134 REQUIRE(format_check_exp1 == s);
135 res = res + s.size();
136 }
137 return res;
138 };
139 BENCHMARK("fmt1.132 format rsrved bench") {
140 volatile size_t res = 0;
141 for( size_t i = 0; i < loops; ++i ) {
142 std::string s = jau::format_string("format_check: %d, %zu", i1, i2);
143 REQUIRE(format_check_exp1 == s);
144 res = res + s.size();
145 }
146 return res;
147 };
148 BENCHMARK("fmtX.132 snprintf rsrved bench") {
149 volatile size_t res = 0;
150 for( size_t i = 0; i < loops; ++i ) {
151 std::string s;
152 const size_t bsz = jau::cfmt::default_string_capacity + 1; // including EOS
153 s.reserve(bsz); // incl. EOS
154 s.resize(bsz - 1); // excl. EOS
155 size_t nchars = std::snprintf(&s[0], bsz, "format_check: %d, %zu", i1, i2);
156 if( nchars < bsz ) {
157 s.resize(nchars);
158 }
159 REQUIRE(format_check_exp1 == s);
160 res = res + nchars;
161 }
162 return res;
163 };
164 BENCHMARK("fmt1.142 format bench") {
165 volatile size_t res = 0;
166 for( size_t i = 0; i < loops; ++i ) {
167 // fa += 0.01f; fb += 0.02f; ++sz1; ++i1; str1.append("X");
168 std::string s = jau::cfmt::format("format_check: %d, %zu", i1, i2);
169 REQUIRE(format_check_exp1 == s);
170 res = res + s.size();
171 }
172 return res;
173 };
174
175}
176
177TEST_CASE("jau_cfmt_benchmark_int_all", "[benchmark][jau][std::string][format_int]") {
178 const size_t loops = 1000; // catch_auto_run ? 1000 : 1000;
179 WARN("Benchmark with " + std::to_string(loops) + " loops");
180 CHECK(true);
181
182 static constexpr const std::string_view format_check_exp1 = "format_check: -1, 2, -3, 4, -5, 6, -7, 8, -9, 10";
183 static constexpr const std::string_view format_check_exp2 = "format_check: -1, 02, -03, 0004, -0005, 000006, -000007, 00000008, -00000009, 0000000010";
184 char i1=-1;
185 unsigned char i2=2;
186
187 short i3=-3;
188 unsigned short i4=4;
189
190 int i5=-5;
191 unsigned int i6=6;
192
193 long i7=-7;
194 unsigned long i8=8;
195
196 ssize_t i9 = -9;
197 size_t i10 = 10;
198
199 BENCHMARK("fmt1.130 formatR rsrved bench") {
200 volatile size_t res = 0;
201 for( size_t i = 0; i < loops; ++i ) {
202 std::string s;
204
205 jau::cfmt::formatR(s, "format_check: %hhd, %hhu, %hd, %hu, %d, %u, %ld, %lu, %zd, %zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
206 REQUIRE(format_check_exp1 == s);
207 res = res + s.size();
208 }
209 return res;
210 };
211 BENCHMARK("fmt1.132 format rsrved bench") {
212 volatile size_t res = 0;
213 for( size_t i = 0; i < loops; ++i ) {
214 std::string s = jau::format_string("format_check: %hhd, %hhu, %hd, %hu, %d, %u, %ld, %lu, %zd, %zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
215 REQUIRE(format_check_exp1 == s);
216 res = res + s.size();
217 }
218 return res;
219 };
220 BENCHMARK("fmtX.132 snprintf rsrved bench") {
221 volatile size_t res = 0;
222 for( size_t i = 0; i < loops; ++i ) {
223 std::string s;
224 const size_t bsz = jau::cfmt::default_string_capacity + 1; // including EOS
225 s.reserve(bsz); // incl. EOS
226 s.resize(bsz - 1); // excl. EOS
227 size_t nchars = std::snprintf(&s[0], bsz, "format_check: %hhd, %hhu, %hd, %hu, %d, %u, %ld, %lu, %zd, %zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
228 if( nchars < bsz ) {
229 s.resize(nchars);
230 }
231 REQUIRE(format_check_exp1 == s);
232 res = res + nchars;
233 }
234 return res;
235 };
236 BENCHMARK("fmt1.142 format bench") {
237 volatile size_t res = 0;
238 for( size_t i = 0; i < loops; ++i ) {
239 // fa += 0.01f; fb += 0.02f; ++sz1; ++i1; str1.append("X");
240 std::string s = jau::cfmt::format("format_check: %hhd, %hhu, %hd, %hu, %d, %u, %ld, %lu, %zd, %zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
241 REQUIRE(format_check_exp1 == s);
242 res = res + s.size();
243 }
244 return res;
245 };
246
247 BENCHMARK("fmtX.150 stringstream bench") {
248 volatile size_t res = 0;
249 for( size_t i = 0; i < loops; ++i ) {
250 std::ostringstream ss1;
251 ss1 << "format_check: "
252 << int(i1) << ", "
253 << unsigned(i2) << ", "
254 << i3 << ", "
255 << i4 << ", "
256 << i5 << ", "
257 << i6 << ", "
258 << i7 << ", "
259 << i8 << ", "
260 << i9 << ", "
261 << i10;
262 std::string s = ss1.str();
263 REQUIRE(format_check_exp1 == s);
264 res = res + s.size();
265 }
266 return res;
267 };
268
269 ///
270 ///
271
272 BENCHMARK("fmt1.230 formatR rsrved bench") {
273 volatile size_t res = 0;
274 for( size_t i = 0; i < loops; ++i ) {
275 std::string s;
277
278 jau::cfmt::formatR(s, "format_check: %01hhd, %02hhu, %03hd, %04hu, %05d, %06u, %07ld, %08lu, %09zd, %010zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
279 REQUIRE(format_check_exp2 == s);
280 res = res + s.size();
281 }
282 return res;
283 };
284 BENCHMARK("fmt1.232 format rsrved bench") {
285 volatile size_t res = 0;
286 for( size_t i = 0; i < loops; ++i ) {
287 std::string s = jau::format_string("format_check: %01hhd, %02hhu, %03hd, %04hu, %05d, %06u, %07ld, %08lu, %09zd, %010zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
288 REQUIRE(format_check_exp2 == s);
289 res = res + s.size();
290 }
291 return res;
292 };
293 BENCHMARK("fmtX.232 snprintf rsrved bench") {
294 volatile size_t res = 0;
295 for( size_t i = 0; i < loops; ++i ) {
296 std::string s;
297 const size_t bsz = jau::cfmt::default_string_capacity + 1; // including EOS
298 s.reserve(bsz); // incl. EOS
299 s.resize(bsz - 1); // excl. EOS
300 size_t nchars = std::snprintf(&s[0], bsz, "format_check: %01hhd, %02hhu, %03hd, %04hu, %05d, %06u, %07ld, %08lu, %09zd, %010zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
301 if( nchars < bsz ) {
302 s.resize(nchars);
303 }
304 REQUIRE(format_check_exp2 == s);
305 res = res + nchars;
306 }
307 return res;
308 };
309 BENCHMARK("fmt1.242 format bench") {
310 volatile size_t res = 0;
311 for( size_t i = 0; i < loops; ++i ) {
312 // fa += 0.01f; fb += 0.02f; ++sz1; ++i1; str1.append("X");
313 std::string s = jau::cfmt::format("format_check: %01hhd, %02hhu, %03hd, %04hu, %05d, %06u, %07ld, %08lu, %09zd, %010zu", i1, i2, i3, i4, i5, i6, i7, i8, i9, i10);
314 REQUIRE(format_check_exp2 == s);
315 res = res + s.size();
316 }
317 return res;
318 };
319
320 BENCHMARK("fmtX.250 stringstream bench") {
321 volatile size_t res = 0;
322 for( size_t i = 0; i < loops; ++i ) {
323 std::ostringstream ss1;
324 ss1 << "format_check: "
325 << std::setfill('0') // undefined with negative numbers, duh!
326 << "-" << std::setw(0) << int(jau::abs(i1)) << ", "
327 << std::setw(2) << unsigned(i2) << ", "
328 << "-" << std::setw(3-1) << jau::abs(i3) << ", "
329 << std::setw(4) << i4 << ", "
330 << "-" << std::setw(5-1) << jau::abs(i5) << ", "
331 << std::setw(6) << i6 << ", "
332 << "-" << std::setw(7-1) << jau::abs(i7) << ", "
333 << std::setw(8) << i8 << ", "
334 << "-" << std::setw(9-1) << jau::abs(i9) << ", "
335 << std::setw(10) << i10;
336 std::string s = ss1.str();
337 REQUIRE(format_check_exp2 == s);
338 res = res + s.size();
339 }
340 return res;
341 };
342
343}
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
Result formatR(std::string &s, size_t maxLen, std::string_view fmt, const Targs &...args) noexcept
Strict format with type validation of arguments against the format string, appending to the given des...
constexpr const size_t default_string_capacity
Default string reserved capacity w/o EOS (511)
std::string format(std::string_view fmt, const Targs &...args) noexcept
Strict format with type validation of arguments against the format string.
std::string format_string(std::string_view fmt, const Args &...args) noexcept
Safely returns a (non-truncated) string according to snprintf() formatting rules using a reserved str...
static int loops
TEST_CASE("jau_cfmt_benchmark_int0", "[benchmark][jau][std::string][format_int]")