add benchmark (issue #12)
This commit is contained in:
parent
2c4e520a17
commit
20cff0757b
4
.gitignore
vendored
4
.gitignore
vendored
@ -8,3 +8,7 @@
|
||||
*.dll
|
||||
*.dylib
|
||||
*.dSYM
|
||||
*.txt
|
||||
*.out
|
||||
bench
|
||||
icu
|
||||
|
||||
33
bench/Makefile
Normal file
33
bench/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
CURL=curl
|
||||
|
||||
CC = cc
|
||||
CFLAGS = -O2 -std=c99 -pedantic -Wall
|
||||
|
||||
all: bench
|
||||
|
||||
LIBMOJIBAKE = ../libmojibake.a
|
||||
|
||||
bench: bench.o util.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ bench.o util.o $(LIBMOJIBAKE)
|
||||
|
||||
DATAURL = https://raw.githubusercontent.com/duerst/eprun/master/benchmark
|
||||
DATAFILES = Deutsch_.txt Japanese_.txt Korean_.txt Vietnamese_.txt
|
||||
|
||||
$(DATAFILES):
|
||||
$(CURL) -O $(DATAURL)/$@
|
||||
|
||||
bench.out: $(DATAFILES) bench
|
||||
./bench -nfkc $(DATAFILES) > $@
|
||||
|
||||
# you may need make CPPFLAGS=... LDFLAGS=... to help it find ICU
|
||||
icu: icu.o util.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ icu.o util.o -licuuc
|
||||
|
||||
icu.out: $(DATAFILES) icu
|
||||
./icu $(DATAFILES) > $@
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CPPFLAGS) -I.. $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.txt bench *.out icu
|
||||
56
bench/bench.c
Normal file
56
bench/bench.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mojibake.h"
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int options = 0;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "-nfkc")) {
|
||||
options |= UTF8PROC_STABLE|UTF8PROC_COMPOSE|UTF8PROC_COMPAT;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-nfkd")) {
|
||||
options |= UTF8PROC_STABLE|UTF8PROC_DECOMPOSE|UTF8PROC_COMPAT;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-nfc")) {
|
||||
options |= UTF8PROC_STABLE|UTF8PROC_COMPOSE;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-nfd")) {
|
||||
options |= UTF8PROC_STABLE|UTF8PROC_DECOMPOSE;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-casefold")) {
|
||||
options |= UTF8PROC_CASEFOLD;
|
||||
continue;
|
||||
}
|
||||
if (argv[i][0] == '-') {
|
||||
fprintf(stderr, "unrecognized option: %s\n", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
uint8_t *src = readfile(argv[i], &len);
|
||||
if (!src) {
|
||||
fprintf(stderr, "error reading %s\n", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
uint8_t *dest;
|
||||
mytime start = gettime();
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
utf8proc_map(src, len, &dest, options);
|
||||
free(dest);
|
||||
}
|
||||
printf("%s: %g\n", argv[i], elapsed(gettime(), start) / 100);
|
||||
free(src);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
61
bench/icu.c
Normal file
61
bench/icu.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ICU4C */
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/ustring.h>
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/unorm2.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
UErrorCode err;
|
||||
UConverter *uc = ucnv_open("UTF8", &err);
|
||||
if (U_FAILURE(err)) return EXIT_FAILURE;
|
||||
|
||||
const UNormalizer2 *NFKC = unorm2_getNFKCInstance(&err);
|
||||
if (U_FAILURE(err)) return EXIT_FAILURE;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
fprintf(stderr, "unrecognized option: %s\n", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
uint8_t *src = readfile(argv[i], &len);
|
||||
if (!src) {
|
||||
fprintf(stderr, "error reading %s\n", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* convert UTF8 data to ICU's UTF16 */
|
||||
UChar *usrc = (UChar*) malloc(2*len * sizeof(UChar));
|
||||
ucnv_toUChars(uc, usrc, 2*len, (char*) src, len, &err);
|
||||
if (U_FAILURE(err)) return EXIT_FAILURE;
|
||||
size_t ulen = u_strlen(usrc);
|
||||
|
||||
/* ICU's insane normalization API requires you to
|
||||
know the size of the destination buffer in advance,
|
||||
or alternatively to repeatly try normalizing and
|
||||
double the buffer size until it succeeds. Here, I just
|
||||
allocate a huge destination buffer to avoid the issue. */
|
||||
UChar *udest = (UChar*) malloc(10*ulen * sizeof(UChar));
|
||||
|
||||
mytime start = gettime();
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
unorm2_normalize(NFKC, usrc, ulen, udest, 10*ulen, &err);
|
||||
if (U_FAILURE(err)) return EXIT_FAILURE;
|
||||
}
|
||||
printf("%s: %g\n", argv[i], elapsed(gettime(), start) / 100);
|
||||
free(udest);
|
||||
free(usrc);
|
||||
free(src);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
39
bench/util.c
Normal file
39
bench/util.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* read file named FILENAME into an array of *len bytes,
|
||||
returning NULL on error */
|
||||
uint8_t *readfile(const char *filename, size_t *len)
|
||||
{
|
||||
*len = 0;
|
||||
struct stat st;
|
||||
if (0 != stat(filename, &st)) return NULL;
|
||||
*len = st.st_size;
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) return NULL;
|
||||
uint8_t *s = (uint8_t *) malloc(sizeof(uint8_t) * *len);
|
||||
if (!s) return NULL;
|
||||
if (fread(s, 1, *len, f) != *len) {
|
||||
free(s);
|
||||
s = NULL;
|
||||
}
|
||||
fclose(f);
|
||||
return s;
|
||||
}
|
||||
|
||||
mytime gettime(void) {
|
||||
mytime t;
|
||||
gettimeofday(&t, NULL);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* time difference in seconds */
|
||||
double elapsed(mytime t1, mytime t0)
|
||||
{
|
||||
return (double)(t1.tv_sec - t0.tv_sec) +
|
||||
(double)(t1.tv_usec - t0.tv_usec) * 1.0E-6;
|
||||
}
|
||||
|
||||
22
bench/util.h
Normal file
22
bench/util.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H 1
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint8_t *readfile(const char *filename, size_t *len);
|
||||
|
||||
typedef struct timeval mytime;
|
||||
mytime gettime(void);
|
||||
double elapsed(mytime t1, mytime t0);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_H */
|
||||
Loading…
Reference in New Issue
Block a user