]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/toolutil/utimer.h
ICU-6.2.10.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / utimer.h
1 /*
2 ************************************************************************
3 * Copyright (c) 1997-2004, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ************************************************************************
6 */
7
8 #ifndef _UTIMER_H
9 #define _UTIMER_H
10
11 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
12 # define VC_EXTRALEAN
13 # define WIN32_LEAN_AND_MEAN
14 # include <windows.h>
15 #else
16 # include <time.h>
17 # include <sys/time.h>
18 # include <unistd.h>
19 #endif
20
21 /**
22 * This API provides functions for performing performance measurement
23 * There are 3 main usage scenarios.
24 * i) Loop until a threshold time is reached:
25 * Example:
26 * <code>
27 * typedef Params Params;
28 * struct Params{
29 * UChar* target;
30 * int32_t targetLen;
31 * const UChar* source;
32 * int32_t sourceLen;
33 * UNormalizationMode mode;
34 * }
35 * void NormFn( void* param){
36 * Params* parameters = ( Params*) param;
37 * UErrorCode error = U_ZERO_ERROR;
38 * unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error);
39 * if(U_FAILURE(error)){
40 * printf("Normalization failed\n");
41 * }
42 * }
43 *
44 * int main(){
45 * // time the normalization function
46 * double timeTaken = 0;
47 * Params param;
48 * param.source // set up the source buffer
49 * param.target // set up the target buffer
50 * .... so on ...
51 * UTimer timer;
52 * // time the loop for 10 seconds at least and find out the loop count and time taken
53 * timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount);
54 * }
55 * </code>
56 *
57 * ii) Measure the time taken
58 * Example:
59 * <code>
60 * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){
61 * int line;
62 * int loops;
63 * UErrorCode error = U_ZERO_ERROR;
64 * UChar* dest=NULL;
65 * int32_t destCapacity=0;
66 * int len =-1;
67 * double elapsedTime = 0;
68 * int retVal=0;
69 *
70 * UChar arr[5000];
71 * dest=arr;
72 * destCapacity = 5000;
73 * UTimer start;
74 *
75 * // Initialize cache and ensure the data is loaded.
76 * // This loop checks for errors in Normalization. Once we pass the initialization
77 * // without errors we can safelly assume that there are no errors while timing the
78 * // funtion
79 * for (loops=0; loops<10; loops++) {
80 * for (line=0; line < gNumFileLines; line++) {
81 * if (opt_uselen) {
82 * len = fileLines[line].len;
83 * }
84 *
85 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
86 * #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
87 * if(retVal==0 ){
88 * fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line);
89 * return 0;
90 * }
91 * #endif
92 * if(U_FAILURE(error)){
93 * fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line);
94 * return 0;
95 * }
96 *
97 * }
98 * }
99 *
100 * //compute the time
101 *
102 * utimer_getTime(&start);
103 * for (loops=0; loops<loopCount; loops++) {
104 * for (line=0; line < gNumFileLines; line++) {
105 * if (opt_uselen) {
106 * len = fileLines[line].len;
107 * }
108 *
109 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
110 *
111 * }
112 * }
113 *
114 * return utimer_getElapsedSeconds(&start);
115 * }
116 * </code>
117 *
118 * iii) Let a higher level function do the calculation of confidence levels etc.
119 * Example:
120 * <code>
121 * void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){
122 * int32_t loops;
123 * for (loops=0; loops<loopCount; loops++) {
124 * unorm_normalize(source,sourceLen,target, targetLen,mode,error);
125 * }
126 * utimer_getTime(timer);
127 * }
128 * void main(const char* argsc, int argv){
129 * // read the file and setup the data
130 * // set up options
131 * UTimer start,timer1, timer2, timer3, timer4;
132 * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken;
133 * switch(opt){
134 * case 0:
135 * utimer_getTime(start);
136 * perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error);
137 * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1);
138 * case 1:
139 * timer_getTime(start);
140 * perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error);
141 * NFCTimeTaken = utimer_getDeltaSeconds(start,timer2);
142 * perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error);
143 * // ........so on .............
144 * }
145 * // calculate confidence levels etc and print
146 *
147 * }
148 *
149 * </code>
150 *
151 */
152
153 typedef struct UTimer UTimer;
154
155 typedef void FuntionToBeTimed(void* param);
156
157
158 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
159
160 struct UTimer{
161 LARGE_INTEGER start;
162 LARGE_INTEGER placeHolder;
163 };
164
165 int uprv_initFrequency(UTimer* timer)
166 {
167 return QueryPerformanceFrequency(&timer->placeHolder);
168 }
169 void uprv_start(UTimer* timer)
170 {
171 QueryPerformanceCounter(&timer->start);
172 }
173 double uprv_delta(UTimer* timer1, UTimer* timer2){
174 return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart);
175 }
176 UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
177 return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart);
178 }
179
180 #else
181
182 struct UTimer{
183 struct timeval start;
184 struct timeval placeHolder;
185 };
186
187 int32_t uprv_initFrequency(UTimer* /*timer*/)
188 {
189 return 0;
190 }
191 void uprv_start(UTimer* timer)
192 {
193 gettimeofday(&timer->start, 0);
194 }
195 double uprv_delta(UTimer* timer1, UTimer* timer2){
196 double t1, t2;
197
198 t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000);
199 t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000);
200 return (t2-t1);
201 }
202 UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
203 return TRUE;
204 }
205
206 #endif
207 /**
208 * Intializes the timer with the current time
209 *
210 * @param timer A pointer to UTimer struct to recieve the current time
211 */
212 U_CAPI void U_EXPORT2
213 utimer_getTime(UTimer* timer){
214 uprv_initFrequency(timer);
215 uprv_start(timer);
216 }
217
218 /**
219 * Returns the difference in times between timer1 and timer2 by subtracting
220 * timer1's time from timer2's time
221 *
222 * @param timer1 A pointer to UTimer struct to be used as starting time
223 * @param timer2 A pointer to UTimer struct to be used as end time
224 * @return Time in seconds
225 */
226 U_CAPI double U_EXPORT2
227 utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){
228 if(uprv_compareFrequency(timer1,timer2)){
229 return uprv_delta(timer1,timer2);
230 }
231 /* got error return -1 */
232 return -1;
233 }
234
235 /**
236 * Returns the time elapsed from the starting time represented by the
237 * UTimer struct pointer passed
238 * @param timer A pointer to UTimer struct to be used as starting time
239 * @return Time elapsed in seconds
240 */
241 U_CAPI double U_EXPORT2
242 utimer_getElapsedSeconds(UTimer* timer){
243 UTimer temp;
244 utimer_getTime(&temp);
245 return uprv_delta(timer,&temp);
246 }
247
248 /**
249 * Executes the function pointed to for a given time and returns exact time
250 * taken and number of iterations of the loop
251 * @param thresholTimeVal
252 * @param loopCount output param to recieve the number of iterations
253 * @param fn The funtion to be executed
254 * @param param Parameters to be passed to the fn
255 * @return the time elapsed in seconds
256 */
257 U_CAPI double U_EXPORT2
258 utimer_loopUntilDone(double thresholdTimeVal,
259 int32_t* loopCount,
260 FuntionToBeTimed fn,
261 void* param){
262 UTimer timer;
263 double currentVal=0;
264 *loopCount = 0;
265 utimer_getTime(&timer);
266 for(;currentVal<thresholdTimeVal;){
267 fn(param);
268 currentVal = utimer_getElapsedSeconds(&timer);
269 *loopCount++;
270 }
271 return currentVal;
272 }
273
274 #endif
275