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 }