]>
Commit | Line | Data |
---|---|---|
729e4ab9 A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
4 | * Copyright (C) 2009, International Business Machines | |
5 | * Corporation and others. All Rights Reserved. | |
6 | * | |
7 | ******************************************************************************* | |
8 | * file name: ucnvavailperf.cpp | |
9 | * encoding: US-ASCII | |
10 | * tab size: 8 (not used) | |
11 | * indentation:4 | |
12 | * | |
13 | * created on: 2009apr06 | |
14 | * created by: Markus W. Scherer | |
15 | * | |
16 | * Test performance (time & memory) of ucnv_countAvailable(), | |
17 | * for a before-and-after comparison of | |
18 | * ticket 6441: make ucnv_countAvailable() not fully load converters | |
19 | * | |
20 | * Run with one optional command-line argument: | |
21 | * You can specify the path to the ICU data directory. | |
22 | * | |
23 | * I built the common (icuuc) library with the following modification, | |
24 | * switching between old (pre-ticket-6441) behavior of actually | |
25 | * trying to load all converters and new behavior of just doing enough | |
26 | * to test availability. | |
27 | * | |
28 | * Code in the ucnv_bld.c haveAvailableConverterList() function: | |
29 | #if 0 | |
30 | // old pre-ticket-6441 behavior | |
31 | ucnv_close(ucnv_createConverter(&tempConverter, converterName, &localStatus)); | |
32 | if (U_SUCCESS(localStatus)) { | |
33 | #else | |
34 | // new behavior | |
35 | if (ucnv_canCreateConverter(converterName, &localStatus)) { | |
36 | #endif | |
37 | */ | |
38 | ||
39 | #include <malloc.h> | |
40 | #include <stdio.h> | |
41 | #include "unicode/utypes.h" | |
42 | #include "unicode/putil.h" | |
43 | #include "unicode/uclean.h" | |
44 | #include "unicode/ucnv.h" | |
45 | #include "unicode/utimer.h" | |
46 | ||
47 | static size_t icuMemUsage = 0; | |
48 | ||
49 | U_CDECL_BEGIN | |
50 | ||
51 | void *U_CALLCONV | |
52 | my_alloc(const void *context, size_t size) { | |
53 | size_t *p = (size_t *)malloc(size + sizeof(size_t)); | |
54 | if (p != NULL) { | |
55 | icuMemUsage += size; | |
56 | *p = size; | |
57 | return p + 1; | |
58 | } else { | |
59 | return NULL; | |
60 | } | |
61 | } | |
62 | ||
63 | void U_CALLCONV | |
64 | my_free(const void *context, void *mem) { | |
65 | if (mem != NULL) { | |
66 | const size_t *p = (const size_t *)mem - 1; | |
67 | icuMemUsage -= *p; | |
68 | free((void *)p); | |
69 | } | |
70 | } | |
71 | ||
72 | // Not used in the common library. | |
73 | void *U_CALLCONV | |
74 | my_realloc(const void *context, void *mem, size_t size) { | |
75 | my_free(context, mem); | |
76 | return NULL; | |
77 | } | |
78 | ||
79 | U_CDECL_END | |
80 | ||
81 | int main(int argc, const char *argv[]) { | |
82 | UErrorCode errorCode = U_ZERO_ERROR; | |
83 | ||
84 | // Hook in our own memory allocation functions so that we can measure | |
85 | // the memory usage. | |
86 | u_setMemoryFunctions(NULL, my_alloc, my_realloc, my_free, &errorCode); | |
87 | if(U_FAILURE(errorCode)) { | |
88 | fprintf(stderr, | |
89 | "u_setMemoryFunctions() failed - %s\n", | |
90 | u_errorName(errorCode)); | |
91 | return errorCode; | |
92 | } | |
93 | ||
94 | if (argc > 1) { | |
95 | printf("u_setDataDirectory(%s)\n", argv[1]); | |
96 | u_setDataDirectory(argv[1]); | |
97 | } | |
98 | ||
99 | // Preload a purely algorithmic converter via an alias, | |
100 | // to make sure that relevant data can be loaded and to set up | |
101 | // caches and such that are needed even if none of the data-driven | |
102 | // converters needs to be loaded. | |
103 | ucnv_close(ucnv_open("ibm-1208", &errorCode)); | |
104 | if(U_FAILURE(errorCode)) { | |
105 | fprintf(stderr, | |
106 | "unable to open UTF-8 converter via an alias - %s\n", | |
107 | u_errorName(errorCode)); | |
108 | return errorCode; | |
109 | } | |
110 | ||
111 | printf("memory usage after ucnv_open(ibm-1208): %lu\n", (long)icuMemUsage); | |
112 | ||
113 | UTimer start_time; | |
114 | utimer_getTime(&start_time); | |
115 | // Measure the time to find out the list of actually available converters. | |
116 | int32_t count = ucnv_countAvailable(); | |
117 | double elapsed = utimer_getElapsedSeconds(&start_time); | |
118 | printf("ucnv_countAvailable() reports that %d converters are available.\n", count); | |
119 | printf("ucnv_countAvailable() took %g seconds to figure this out.\n", elapsed); | |
120 | printf("memory usage after ucnv_countAvailable(): %lu\n", (long)icuMemUsage); | |
121 | ||
122 | ucnv_flushCache(); | |
123 | printf("memory usage after ucnv_flushCache(): %lu\n", (long)icuMemUsage); | |
124 | ||
125 | u_cleanup(); | |
126 | printf("memory usage after u_cleanup(): %lu\n", (long)icuMemUsage); | |
127 | ||
128 | return 0; | |
129 | } |