diff --git a/glib/tests/utf8-performance.c b/glib/tests/utf8-performance.c index d3142852f..5049b99e9 100644 --- a/glib/tests/utf8-performance.c +++ b/glib/tests/utf8-performance.c @@ -35,24 +35,33 @@ static const char str_cyrillic[] = /* First sentence from the Wikipedia article: * http://zh.wikipedia.org/w/index.php?title=%E6%B1%89%E5%AD%97&oldid=13053137 */ -static const char str_chinese[] = +static const char str_han[] = "漢字,亦稱中文字、中国字,在台灣又被稱為國字,是漢字文化圈廣泛使用的一種文字,屬於表意文字的詞素音節文字"; typedef int (* GrindFunc) (const char *, gsize); +#define GRIND_LOOP_BEGIN \ + { \ + int i; \ + for (i = 0; i < NUM_ITERATIONS; i++) + +#define GRIND_LOOP_END \ + } + static int grind_get_char (const char *str, gsize len) { gunichar acc = 0; - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { const char *p = str; - while (*p) { - acc += g_utf8_get_char (p); - p = g_utf8_next_char (p); - } + while (*p) + { + acc += g_utf8_get_char (p); + p = g_utf8_next_char (p); + } } + GRIND_LOOP_END; return acc; } @@ -60,28 +69,29 @@ static int grind_get_char_validated (const char *str, gsize len) { gunichar acc = 0; - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { const char *p = str; - while (*p) { - acc += g_utf8_get_char_validated (p, -1); - p = g_utf8_next_char (p); - } + while (*p) + { + acc += g_utf8_get_char_validated (p, -1); + p = g_utf8_next_char (p); + } } + GRIND_LOOP_END; return acc; } static int grind_utf8_to_ucs4 (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { gunichar *ustr; ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL); g_free (ustr); } + GRIND_LOOP_END; return 0; } @@ -89,8 +99,7 @@ static int grind_get_char_backwards (const char *str, gsize len) { gunichar acc = 0; - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { const char *p = str + len; do @@ -100,69 +109,78 @@ grind_get_char_backwards (const char *str, gsize len) } while (p != str); } + GRIND_LOOP_END; return acc; } static int grind_utf8_to_ucs4_sized (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { gunichar *ustr; ustr = g_utf8_to_ucs4 (str, len, NULL, NULL, NULL); g_free (ustr); } + GRIND_LOOP_END; return 0; } static int grind_utf8_to_ucs4_fast (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { gunichar *ustr; ustr = g_utf8_to_ucs4_fast (str, -1, NULL); g_free (ustr); } + GRIND_LOOP_END; return 0; } static int grind_utf8_to_ucs4_fast_sized (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN { gunichar *ustr; ustr = g_utf8_to_ucs4_fast (str, len, NULL); g_free (ustr); } + GRIND_LOOP_END; return 0; } static int grind_utf8_validate (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN g_utf8_validate (str, -1, NULL); + GRIND_LOOP_END; return 0; } static int grind_utf8_validate_sized (const char *str, gsize len) { - int i; - for (i = 0; i < NUM_ITERATIONS; i++) + GRIND_LOOP_BEGIN g_utf8_validate (str, len, NULL); + GRIND_LOOP_END; return 0; } +typedef struct _GrindData { + GrindFunc func; + const char *str; +} GrindData; + static void -perform_for (GrindFunc grind_func, const char *str, const char *label) +perform (gconstpointer data) { + GrindData *gd = (GrindData *) data; + GrindFunc grind_func = gd->func; + const char *str = gd->str; gsize len; gulong bytes_ground; gdouble time_elapsed; @@ -179,21 +197,32 @@ perform_for (GrindFunc grind_func, const char *str, const char *label) result = ((gdouble) bytes_ground / time_elapsed) * 1.0e-6; - g_test_maximized_result (result, "%-9s %6.1f MB/s", label, result); + g_test_maximized_result (result, "%7.1f MB/s", result); + + g_slice_free (GrindData, gd); } static void -perform (gconstpointer data) +add_cases(const char *path, GrindFunc func) { - GrindFunc grind_func = (GrindFunc) data; +#define ADD_CASE(script) \ + G_STMT_START { \ + GrindData *gd; \ + gchar *full_path; \ + gd = g_slice_new0(GrindData); \ + gd->func = func; \ + gd->str = str_##script; \ + full_path = g_strdup_printf("%s/" #script, path); \ + g_test_add_data_func (full_path, gd, perform); \ + g_free (full_path); \ + } G_STMT_END - if (!g_test_perf ()) - return; + ADD_CASE(ascii); + ADD_CASE(latin1); + ADD_CASE(cyrillic); + ADD_CASE(han); - perform_for (grind_func, str_ascii, "ASCII:"); - perform_for (grind_func, str_latin1, "Latin-1:"); - perform_for (grind_func, str_cyrillic, "Cyrillic:"); - perform_for (grind_func, str_chinese, "Chinese:"); +#undef ADD_CASE } int @@ -203,15 +232,15 @@ main (int argc, char **argv) if (g_test_perf ()) { - g_test_add_data_func ("/utf8/perf/get_char", grind_get_char, perform); - g_test_add_data_func ("/utf8/perf/get_char-backwards", grind_get_char_backwards, perform); - g_test_add_data_func ("/utf8/perf/get_char_validated", grind_get_char_validated, perform); - g_test_add_data_func ("/utf8/perf/utf8_to_ucs4", grind_utf8_to_ucs4, perform); - g_test_add_data_func ("/utf8/perf/utf8_to_ucs4-sized", grind_utf8_to_ucs4_sized, perform); - g_test_add_data_func ("/utf8/perf/utf8_to_ucs4_fast", grind_utf8_to_ucs4_fast, perform); - g_test_add_data_func ("/utf8/perf/utf8_to_ucs4_fast-sized", grind_utf8_to_ucs4_fast_sized, perform); - g_test_add_data_func ("/utf8/perf/utf8_validate", grind_utf8_validate, perform); - g_test_add_data_func ("/utf8/perf/utf8_validate-sized", grind_utf8_validate_sized, perform); + add_cases ("/utf8/perf/get_char", grind_get_char); + add_cases ("/utf8/perf/get_char-backwards", grind_get_char_backwards); + add_cases ("/utf8/perf/get_char_validated", grind_get_char_validated); + add_cases ("/utf8/perf/utf8_to_ucs4", grind_utf8_to_ucs4); + add_cases ("/utf8/perf/utf8_to_ucs4-sized", grind_utf8_to_ucs4_sized); + add_cases ("/utf8/perf/utf8_to_ucs4_fast", grind_utf8_to_ucs4_fast); + add_cases ("/utf8/perf/utf8_to_ucs4_fast-sized", grind_utf8_to_ucs4_fast_sized); + add_cases ("/utf8/perf/utf8_validate", grind_utf8_validate); + add_cases ("/utf8/perf/utf8_validate-sized", grind_utf8_validate_sized); } return g_test_run ();