1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup test
36 * @ingroup test
37 * @brief skeleton file
38 *
39 * This is a speed test.
40 *
41 * Character case needs to be very fast but
42 * _ the simple "or" formula doesn't work with the extended character set
43 * _ the simple sub,or,add formula doesn't work with the full character set
44 *
45 * So it will probably be done using a lookup table.
46 * Each test covers one method, the first one points to the current choosen method.
47 *
48 * One solution may be better on a different architecture so we may want to try on other CPUs. e.g.: ARM and RISC-V
49 *
50 */
51
52 #include <dnscore/dnscore.h>
53 #include <ctype.h>
54 #include <dnscore/format.h>
55
56 #define BENCH_LOOPS 100000
57 #define FQDN_COUNT 12
58 #define LONG_STRING_SIZE 0x1000000
59
60 static char *names[FQDN_COUNT] =
61 {
62 "www.e.eu.",
63 "www.eu.eu.",
64 "www.ode.eu.",
65 "www.code.eu.",
66 "www.eurid.eu.",
67 "www.yadifa.eu.",
68 "www.zorglub.eu.",
69 "www.mountain.eu.",
70 "www.something.eu.",
71 "www.somethingsomething.eu.",
72 "www.somethingsomethingelse.eu.",
73 "www._#!$*\\0123456789abcdefghijklmnopqrstuvwxyz.eu."
74 };
75
76 static u8 **fqdns = NULL;
77
78 static u8 *long_string = NULL;
79 static size_t long_string_size = 0;
80 static u8 *long_string_target = NULL;
81
test_cases_prepare()82 static void test_cases_prepare()
83 {
84 u8 tmp[MAX_DOMAIN_LENGTH];
85
86 srand(0);
87
88 fqdns = malloc(FQDN_COUNT * FQDN_COUNT * sizeof(u8*));
89
90 if(fqdns == NULL)
91 {
92 exit(2);
93 }
94
95 for(int i = 0; i < FQDN_COUNT; ++i)
96 {
97 for(int j = 0; j < FQDN_COUNT; ++j)
98 {
99 cstr_to_dnsname(tmp, names[i]);
100
101 if(j > 0)
102 {
103 u8 *p = &tmp[0];
104 for(u8 n = *p++; n != 0; n = *p++)
105 {
106 for(u8 k = 0; k < n; ++k)
107 {
108 if(rand() & 1)
109 {
110 p[k] = tolower(p[k]);
111 }
112 else
113 {
114 p[k] = toupper(p[k]);
115 }
116 }
117 }
118 }
119
120 fqdns[i * FQDN_COUNT + j] = dnsname_zdup(tmp);
121 }
122 }
123
124 long_string = malloc(LONG_STRING_SIZE * 2);
125
126 if(long_string == NULL)
127 {
128 exit(2);
129 }
130
131 long_string_target = &long_string[LONG_STRING_SIZE];
132
133 for(int i = 0; i < LONG_STRING_SIZE; ++i)
134 {
135 long_string[i] = (u8)rand();
136 }
137 long_string[LONG_STRING_SIZE - 1] = '\0';
138 long_string_size = LONG_STRING_SIZE;
139 }
140
test_cases_equals()141 static void test_cases_equals()
142 {
143 s64 start = timeus();
144
145 for(int l = 0; l < BENCH_LOOPS; ++l)
146 {
147 for(int i = 0; i < FQDN_COUNT; ++i)
148 {
149 for(int j = 1; j < FQDN_COUNT; ++j)
150 {
151 u8 *a = fqdns[i * FQDN_COUNT + 0];
152 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
153 if(!dnsname_equals_ignorecase(a, b))
154 {
155 formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
156 exit(1);
157 }
158 }
159 }
160 }
161
162 s64 stop = timeus();
163
164 formatln("test_cases_equals : time: %lli", stop - start);
165 }
166
test_cases_equals1()167 static void test_cases_equals1()
168 {
169 s64 start = timeus();
170
171 for(int l = 0; l < BENCH_LOOPS; ++l)
172 {
173 for(int i = 0; i < FQDN_COUNT; ++i)
174 {
175 for(int j = 1; j < FQDN_COUNT; ++j)
176 {
177 u8 *a = fqdns[i * FQDN_COUNT + 0];
178 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
179 if(!dnsname_equals_ignorecase1(a, b))
180 {
181 formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
182 exit(1);
183 }
184 }
185 }
186 }
187
188 s64 stop = timeus();
189
190 formatln("test_cases_equals1: time: %lli", stop - start);
191 }
192
193
test_cases_equals2()194 static void test_cases_equals2()
195 {
196 s64 start = timeus();
197
198 for(int l = 0; l < BENCH_LOOPS; ++l)
199 {
200 for(int i = 0; i < FQDN_COUNT; ++i)
201 {
202 for(int j = 1; j < FQDN_COUNT; ++j)
203 {
204 u8 *a = fqdns[i * FQDN_COUNT + 0];
205 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
206 if(!dnsname_equals_ignorecase2(a, b))
207 {
208 formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
209 exit(1);
210 }
211 }
212 }
213 }
214
215 s64 stop = timeus();
216
217 formatln("test_cases_equals2: time: %lli", stop - start);
218 }
219
test_cases_equals3()220 static void test_cases_equals3()
221 {
222 s64 start = timeus();
223
224 for(int l = 0; l < BENCH_LOOPS; ++l)
225 {
226 for(int i = 0; i < FQDN_COUNT; ++i)
227 {
228 for(int j = 1; j < FQDN_COUNT; ++j)
229 {
230 u8 *a = fqdns[i * FQDN_COUNT + 0];
231 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
232 if(!dnsname_equals_ignorecase3(a, b))
233 {
234 formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
235 exit(1);
236 }
237 }
238 }
239 }
240
241 s64 stop = timeus();
242
243 formatln("test_cases_equals3: time: %lli", stop - start);
244 }
245
test_label_cases_equals()246 static void test_label_cases_equals()
247 {
248 s64 start = timeus();
249
250 for(int l = 0; l < BENCH_LOOPS; ++l)
251 {
252 for(int i = 0; i < FQDN_COUNT; ++i)
253 {
254 for(int j = 1; j < FQDN_COUNT; ++j)
255 {
256 u8 *a = fqdns[i * FQDN_COUNT + 0];
257 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
258 a += *a + 1;
259 b += *b + 1;
260 if(!dnslabel_equals_ignorecase_left(a, b))
261 {
262 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
263 exit(1);
264 }
265 }
266 }
267 }
268
269 s64 stop = timeus();
270
271 formatln("test_label_cases_equal : time: %lli", stop - start);
272 }
273
test_label_cases_equals1()274 static void test_label_cases_equals1()
275 {
276 s64 start = timeus();
277
278 for(int l = 0; l < BENCH_LOOPS; ++l)
279 {
280 for(int i = 0; i < FQDN_COUNT; ++i)
281 {
282 for(int j = 1; j < FQDN_COUNT; ++j)
283 {
284 u8 *a = fqdns[i * FQDN_COUNT + 0];
285 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
286 a += *a + 1;
287 b += *b + 1;
288 if(!dnslabel_equals_ignorecase_left1(a, b))
289 {
290 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
291 exit(1);
292 }
293 }
294 }
295 }
296
297 s64 stop = timeus();
298
299 formatln("test_label_cases_equal1: time: %lli", stop - start);
300 }
301
test_label_cases_equals2()302 static void test_label_cases_equals2()
303 {
304 s64 start = timeus();
305
306 for(int l = 0; l < BENCH_LOOPS; ++l)
307 {
308 for(int i = 0; i < FQDN_COUNT; ++i)
309 {
310 for(int j = 1; j < FQDN_COUNT; ++j)
311 {
312 u8 *a = fqdns[i * FQDN_COUNT + 0];
313 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
314 a += *a + 1;
315 b += *b + 1;
316 if(!dnslabel_equals_ignorecase_left2(a, b))
317 {
318 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
319 exit(1);
320 }
321 }
322 }
323 }
324
325 s64 stop = timeus();
326
327 formatln("test_label_cases_equal2: time: %lli", stop - start);
328 }
329
test_label_cases_equals3()330 static void test_label_cases_equals3()
331 {
332 s64 start = timeus();
333
334 for(int l = 0; l < BENCH_LOOPS; ++l)
335 {
336 for(int i = 0; i < FQDN_COUNT; ++i)
337 {
338 for(int j = 1; j < FQDN_COUNT; ++j)
339 {
340 u8 *a = fqdns[i * FQDN_COUNT + 0];
341 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
342 a += *a + 1;
343 b += *b + 1;
344 if(!dnslabel_equals_ignorecase_left3(a, b))
345 {
346 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
347 exit(1);
348 }
349 }
350 }
351 }
352
353 s64 stop = timeus();
354
355 formatln("test_label_cases_equal3: time: %lli", stop - start);
356 }
357
test_label_cases_equals4()358 static void test_label_cases_equals4()
359 {
360 s64 start = timeus();
361
362 for(int l = 0; l < BENCH_LOOPS; ++l)
363 {
364 for(int i = 0; i < FQDN_COUNT; ++i)
365 {
366 for(int j = 1; j < FQDN_COUNT; ++j)
367 {
368 u8 *a = fqdns[i * FQDN_COUNT + 0];
369 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
370 a += *a + 1;
371 b += *b + 1;
372 if(!dnslabel_equals_ignorecase_left4(a, b))
373 {
374 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
375 exit(1);
376 }
377 }
378 }
379 }
380
381 s64 stop = timeus();
382
383 formatln("test_label_cases_equal4: time: %lli", stop - start);
384 }
385
test_label_cases_equals5()386 static void test_label_cases_equals5()
387 {
388 s64 start = timeus();
389
390 for(int l = 0; l < BENCH_LOOPS; ++l)
391 {
392 for(int i = 0; i < FQDN_COUNT; ++i)
393 {
394 for(int j = 1; j < FQDN_COUNT; ++j)
395 {
396 u8 *a = fqdns[i * FQDN_COUNT + 0];
397 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
398 a += *a + 1;
399 b += *b + 1;
400 if(!dnslabel_equals_ignorecase_left5(a, b))
401 {
402 formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
403 exit(1);
404 }
405 }
406 }
407 }
408
409 s64 stop = timeus();
410
411 formatln("test_label_cases_equal5: time: %lli", stop - start);
412 }
413
test_string_tolower()414 static void test_string_tolower()
415 {
416 s64 start = timeus();
417
418 for(size_t i = 0; i < long_string_size; ++i)
419 {
420 long_string_target[i] = LOCASE(long_string[i]);
421 }
422
423 s64 stop = timeus();
424
425 formatln("test_string_tolower: time: %lli", stop - start);
426 }
427
test_string_tolower1()428 static void test_string_tolower1()
429 {
430 s64 start = timeus();
431
432 for(size_t i = 0; i < long_string_size; ++i)
433 {
434 long_string_target[i] = tolower(long_string[i]);
435 }
436
437 s64 stop = timeus();
438
439 formatln("test_string_tolower1: time: %lli", stop - start);
440 }
441
test_string_tolower2()442 static void test_string_tolower2()
443 {
444 s64 start = timeus();
445
446 for(size_t i = 0; i < long_string_size; ++i)
447 {
448 long_string_target[i] = __LOCASE_TABLE__[long_string[i]];
449 }
450
451 s64 stop = timeus();
452
453 formatln("test_string_tolower2: time: %lli", stop - start);
454 }
455
456 int
main(int argc,char * argv[])457 main(int argc, char *argv[])
458 {
459 (void)argc;
460 (void)argv;
461 /* initializes the core library */
462 dnscore_init();
463
464 test_cases_prepare();
465
466 test_cases_equals();
467 test_cases_equals();
468 test_cases_equals1();
469 test_cases_equals1();
470 test_cases_equals2();
471 test_cases_equals2();
472 test_cases_equals3();
473 test_cases_equals3();
474
475 test_label_cases_equals();
476 test_label_cases_equals();
477 test_label_cases_equals1();
478 test_label_cases_equals1();
479 test_label_cases_equals2();
480 test_label_cases_equals2();
481 test_label_cases_equals3();
482 test_label_cases_equals3();
483 test_label_cases_equals4();
484 test_label_cases_equals4();
485 test_label_cases_equals5();
486 test_label_cases_equals5();
487
488 test_string_tolower();
489 test_string_tolower();
490 test_string_tolower1();
491 test_string_tolower1();
492 test_string_tolower2();
493 test_string_tolower2();
494
495 flushout();
496 flusherr();
497 fflush(NULL);
498
499 dnscore_finalize();
500
501 return EXIT_SUCCESS;
502 }
503