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