util.c - libgrapheme - unicode string library
(HTM) git clone git://git.suckless.org/libgrapheme
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
util.c (2703B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 #include "../gen/types.h"
8 #include "../grapheme.h"
9 #include "util.h"
10
11 uint_least32_t *
12 generate_cp_test_buffer(const struct break_test *test, size_t testlen,
13 size_t *buflen)
14 {
15 size_t i, j, off;
16 uint_least32_t *buf;
17
18 /* allocate and generate buffer */
19 for (i = 0, *buflen = 0; i < testlen; i++) {
20 *buflen += test[i].cplen;
21 }
22 if (!(buf = calloc(*buflen, sizeof(*buf)))) {
23 fprintf(stderr,
24 "generate_test_buffer: calloc: Out of memory.\n");
25 exit(1);
26 }
27 for (i = 0, off = 0; i < testlen; i++) {
28 for (j = 0; j < test[i].cplen; j++) {
29 buf[off + j] = test[i].cp[j];
30 }
31 off += test[i].cplen;
32 }
33
34 return buf;
35 }
36
37 char *
38 generate_utf8_test_buffer(const struct break_test *test, size_t testlen,
39 size_t *buflen)
40 {
41 size_t i, j, off, ret;
42 char *buf;
43
44 /* allocate and generate buffer */
45 for (i = 0, *buflen = 0; i < testlen; i++) {
46 for (j = 0; j < test[i].cplen; j++) {
47 *buflen += grapheme_encode_utf8(test[i].cp[j], NULL, 0);
48 }
49 }
50 (*buflen)++; /* terminating NUL-byte */
51 if (!(buf = malloc(*buflen))) {
52 fprintf(stderr,
53 "generate_test_buffer: malloc: Out of memory.\n");
54 exit(1);
55 }
56 for (i = 0, off = 0; i < testlen; i++) {
57 for (j = 0; j < test[i].cplen; j++, off += ret) {
58 if ((ret = grapheme_encode_utf8(
59 test[i].cp[j], buf + off, *buflen - off)) >
60 (*buflen - off)) {
61 /* shouldn't happen */
62 fprintf(stderr, "generate_utf8_test_buffer: "
63 "Buffer too small.\n");
64 exit(1);
65 }
66 }
67 }
68 buf[*buflen - 1] = '\0';
69
70 return buf;
71 }
72
73 static double
74 time_diff(clock_t a, clock_t b)
75 {
76 return (double)(b - a) / CLOCKS_PER_SEC;
77 }
78
79 void
80 run_benchmark(void (*func)(const void *), const void *payload, const char *name,
81 const char *comment, const char *unit, double *baseline,
82 size_t num_iterations, size_t units_per_iteration)
83 {
84 clock_t start, end;
85 size_t i;
86 double diff;
87
88 printf("\t%s ", name);
89 fflush(stdout);
90
91 start = clock();
92 for (i = 0; i < num_iterations; i++) {
93 func(payload);
94
95 if (i % (num_iterations / 10) == 0) {
96 printf(".");
97 fflush(stdout);
98 }
99 }
100 end = clock();
101 diff = time_diff(start, end) / (double)num_iterations /
102 (double)units_per_iteration;
103
104 if (isnan(*baseline)) {
105 *baseline = diff;
106 printf(" avg. %.3es/%s (baseline)\n", diff, unit);
107 } else {
108 printf(" avg. %.3es/%s (%.2f%% %s%s%s)\n", diff, unit,
109 fabs(1.0 - diff / *baseline) * 100,
110 (diff < *baseline) ? "faster" : "slower",
111 comment ? ", " : "", comment ? comment : "");
112 }
113 }