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