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 }