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