1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ************************************************************************
5 * Copyright (c) 1997-2012, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 ************************************************************************
13 #include "unicode/utypes.h"
15 #if U_PLATFORM_USES_ONLY_WIN32_API
17 # define WIN32_LEAN_AND_MEAN
20 # if U_PLATFORM == U_PF_OS390 && !defined(__UU)
21 # define __UU /* Universal Unix - for struct timeval */
24 # include <sys/time.h>
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:
34 * typedef Params Params;
38 * const UChar* source;
40 * UNormalizationMode mode;
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");
52 * // time the normalization function
53 * double timeTaken = 0;
55 * param.source // set up the source buffer
56 * param.target // set up the target buffer
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);
64 * ii) Measure the time taken
67 * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){
70 * UErrorCode error = U_ZERO_ERROR;
72 * int32_t destCapacity=0;
74 * double elapsedTime = 0;
79 * destCapacity = 5000;
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
86 * for (loops=0; loops<10; loops++) {
87 * for (line=0; line < gNumFileLines; line++) {
89 * len = fileLines[line].len;
92 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
93 * #if U_PLATFORM_HAS_WIN32_API
95 * fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line);
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);
109 * utimer_getTime(&start);
110 * for (loops=0; loops<loopCount; loops++) {
111 * for (line=0; line < gNumFileLines; line++) {
113 * len = fileLines[line].len;
116 * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
121 * return utimer_getElapsedSeconds(&start);
125 * iii) Let a higher level function do the calculation of confidence levels etc.
128 * void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){
130 * for (loops=0; loops<loopCount; loops++) {
131 * unorm_normalize(source,sourceLen,target, targetLen,mode,error);
133 * utimer_getTime(timer);
135 * void main(const char* argsc, int argv){
136 * // read the file and setup the data
138 * UTimer start,timer1, timer2, timer3, timer4;
139 * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken;
142 * utimer_getTime(start);
143 * perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error);
144 * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1);
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 .............
152 * // calculate confidence levels etc and print
160 typedef struct UTimer UTimer
;
162 typedef void FuntionToBeTimed(void* param
);
165 #if U_PLATFORM_USES_ONLY_WIN32_API
169 LARGE_INTEGER placeHolder
;
172 static int uprv_initFrequency(UTimer
* timer
)
174 return QueryPerformanceFrequency(&timer
->placeHolder
);
176 static void uprv_start(UTimer
* timer
)
178 QueryPerformanceCounter(&timer
->start
);
180 static double uprv_delta(UTimer
* timer1
, UTimer
* timer2
){
181 return ((double)(timer2
->start
.QuadPart
- timer1
->start
.QuadPart
))/((double)timer1
->placeHolder
.QuadPart
);
183 static UBool
uprv_compareFrequency(UTimer
* timer1
, UTimer
* timer2
){
184 return (timer1
->placeHolder
.QuadPart
== timer2
->placeHolder
.QuadPart
);
190 struct timeval start
;
191 struct timeval placeHolder
;
194 static int32_t uprv_initFrequency(UTimer
* /*timer*/)
198 static void uprv_start(UTimer
* timer
)
200 gettimeofday(&timer
->start
, 0);
202 static double uprv_delta(UTimer
* timer1
, UTimer
* timer2
){
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);
209 static UBool
uprv_compareFrequency(UTimer
* /*timer1*/, UTimer
* /*timer2*/){
215 * Intializes the timer with the current time
217 * @param timer A pointer to UTimer struct to recieve the current time
219 static inline void U_EXPORT2
220 utimer_getTime(UTimer
* timer
){
221 uprv_initFrequency(timer
);
226 * Returns the difference in times between timer1 and timer2 by subtracting
227 * timer1's time from timer2's time
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
233 static inline double U_EXPORT2
234 utimer_getDeltaSeconds(UTimer
* timer1
, UTimer
* timer2
){
235 if(uprv_compareFrequency(timer1
,timer2
)){
236 return uprv_delta(timer1
,timer2
);
238 /* got error return -1 */
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
248 static inline double U_EXPORT2
249 utimer_getElapsedSeconds(UTimer
* timer
){
251 utimer_getTime(&temp
);
252 return uprv_delta(timer
,&temp
);
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
264 static inline double U_EXPORT2
265 utimer_loopUntilDone(double thresholdTimeVal
,
272 utimer_getTime(&timer
);
273 for(;currentVal
<thresholdTimeVal
;){
275 currentVal
= utimer_getElapsedSeconds(&timer
);