2002-10-10 01:04:15 +00:00
|
|
|
/*
|
|
|
|
************************************************************************
|
2010-07-12 18:03:29 +00:00
|
|
|
* Copyright (c) 1997-2010, International Business Machines
|
2002-10-10 01:04:15 +00:00
|
|
|
* Corporation and others. All Rights Reserved.
|
|
|
|
************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _UTIMER_H
|
|
|
|
#define _UTIMER_H
|
|
|
|
|
2005-02-17 00:19:44 +00:00
|
|
|
#include "unicode/utypes.h"
|
|
|
|
|
|
|
|
#if defined(U_WINDOWS)
|
2004-10-21 06:40:36 +00:00
|
|
|
# define VC_EXTRALEAN
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
2002-10-10 01:04:15 +00:00
|
|
|
# include <windows.h>
|
|
|
|
#else
|
2009-07-18 02:35:27 +00:00
|
|
|
# if defined(OS390)
|
|
|
|
# define __UU /* Universal Unix - for struct timeval */
|
|
|
|
# endif
|
2004-04-02 01:41:25 +00:00
|
|
|
# include <time.h>
|
2002-10-10 01:04:15 +00:00
|
|
|
# include <sys/time.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This API provides functions for performing performance measurement
|
|
|
|
* There are 3 main usage scenarios.
|
|
|
|
* i) Loop until a threshold time is reached:
|
2002-10-10 20:07:17 +00:00
|
|
|
* Example:
|
2002-10-10 01:04:15 +00:00
|
|
|
* <code>
|
2002-10-10 20:07:17 +00:00
|
|
|
* typedef Params Params;
|
|
|
|
* struct Params{
|
|
|
|
* UChar* target;
|
|
|
|
* int32_t targetLen;
|
|
|
|
* const UChar* source;
|
|
|
|
* int32_t sourceLen;
|
|
|
|
* UNormalizationMode mode;
|
|
|
|
* }
|
|
|
|
* void NormFn( void* param){
|
|
|
|
* Params* parameters = ( Params*) param;
|
|
|
|
* UErrorCode error = U_ZERO_ERROR;
|
|
|
|
* unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error);
|
|
|
|
* if(U_FAILURE(error)){
|
|
|
|
* printf("Normalization failed\n");
|
|
|
|
* }
|
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2002-10-10 20:07:17 +00:00
|
|
|
* int main(){
|
|
|
|
* // time the normalization function
|
|
|
|
* double timeTaken = 0;
|
|
|
|
* Params param;
|
|
|
|
* param.source // set up the source buffer
|
|
|
|
* param.target // set up the target buffer
|
|
|
|
* .... so on ...
|
|
|
|
* UTimer timer;
|
2002-10-10 01:04:15 +00:00
|
|
|
* // time the loop for 10 seconds at least and find out the loop count and time taken
|
2002-10-10 20:07:17 +00:00
|
|
|
* timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount);
|
|
|
|
* }
|
|
|
|
* </code>
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
|
|
|
* ii) Measure the time taken
|
|
|
|
* Example:
|
|
|
|
* <code>
|
2005-02-17 00:19:44 +00:00
|
|
|
* double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){
|
|
|
|
* int line;
|
|
|
|
* int loops;
|
|
|
|
* UErrorCode error = U_ZERO_ERROR;
|
|
|
|
* UChar* dest=NULL;
|
|
|
|
* int32_t destCapacity=0;
|
|
|
|
* int len =-1;
|
|
|
|
* double elapsedTime = 0;
|
|
|
|
* int retVal=0;
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* UChar arr[5000];
|
|
|
|
* dest=arr;
|
|
|
|
* destCapacity = 5000;
|
|
|
|
* UTimer start;
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* // Initialize cache and ensure the data is loaded.
|
|
|
|
* // This loop checks for errors in Normalization. Once we pass the initialization
|
|
|
|
* // without errors we can safelly assume that there are no errors while timing the
|
|
|
|
* // funtion
|
|
|
|
* for (loops=0; loops<10; loops++) {
|
|
|
|
* for (line=0; line < gNumFileLines; line++) {
|
|
|
|
* if (opt_uselen) {
|
|
|
|
* len = fileLines[line].len;
|
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
|
|
|
|
* #if defined(U_WINDOWS)
|
|
|
|
* if(retVal==0 ){
|
|
|
|
* fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line);
|
|
|
|
* return 0;
|
2002-10-10 20:07:17 +00:00
|
|
|
* }
|
2005-02-17 00:19:44 +00:00
|
|
|
* #endif
|
|
|
|
* if(U_FAILURE(error)){
|
|
|
|
* fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line);
|
|
|
|
* return 0;
|
|
|
|
* }
|
|
|
|
*
|
2002-10-10 20:07:17 +00:00
|
|
|
* }
|
2005-02-17 00:19:44 +00:00
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* //compute the time
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* utimer_getTime(&start);
|
|
|
|
* for (loops=0; loops<loopCount; loops++) {
|
|
|
|
* for (line=0; line < gNumFileLines; line++) {
|
|
|
|
* if (opt_uselen) {
|
|
|
|
* len = fileLines[line].len;
|
2002-10-10 20:07:17 +00:00
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2005-02-17 00:19:44 +00:00
|
|
|
* retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
|
|
|
|
*
|
|
|
|
* }
|
2002-10-10 20:07:17 +00:00
|
|
|
* }
|
2005-02-17 00:19:44 +00:00
|
|
|
*
|
|
|
|
* return utimer_getElapsedSeconds(&start);
|
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
* </code>
|
|
|
|
*
|
|
|
|
* iii) Let a higher level function do the calculation of confidence levels etc.
|
|
|
|
* Example:
|
|
|
|
* <code>
|
2002-10-10 20:07:17 +00:00
|
|
|
* void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){
|
|
|
|
* int32_t loops;
|
|
|
|
* for (loops=0; loops<loopCount; loops++) {
|
|
|
|
* unorm_normalize(source,sourceLen,target, targetLen,mode,error);
|
|
|
|
* }
|
|
|
|
* utimer_getTime(timer);
|
|
|
|
* }
|
|
|
|
* void main(const char* argsc, int argv){
|
|
|
|
* // read the file and setup the data
|
|
|
|
* // set up options
|
|
|
|
* UTimer start,timer1, timer2, timer3, timer4;
|
|
|
|
* double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken;
|
|
|
|
* switch(opt){
|
|
|
|
* case 0:
|
|
|
|
* utimer_getTime(start);
|
|
|
|
* perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error);
|
|
|
|
* NFDTimeTaken = utimer_getDeltaSeconds(start,timer1);
|
|
|
|
* case 1:
|
|
|
|
* timer_getTime(start);
|
|
|
|
* perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error);
|
|
|
|
* NFCTimeTaken = utimer_getDeltaSeconds(start,timer2);
|
|
|
|
* perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error);
|
|
|
|
* // ........so on .............
|
|
|
|
* }
|
|
|
|
* // calculate confidence levels etc and print
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
2002-10-10 20:07:17 +00:00
|
|
|
* }
|
2002-10-10 01:04:15 +00:00
|
|
|
*
|
|
|
|
* </code>
|
2002-10-10 20:07:17 +00:00
|
|
|
*
|
2002-10-10 01:04:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct UTimer UTimer;
|
|
|
|
|
|
|
|
typedef void FuntionToBeTimed(void* param);
|
|
|
|
|
|
|
|
|
2005-02-17 00:19:44 +00:00
|
|
|
#if defined(U_WINDOWS)
|
2002-10-10 01:04:15 +00:00
|
|
|
|
|
|
|
struct UTimer{
|
|
|
|
LARGE_INTEGER start;
|
|
|
|
LARGE_INTEGER placeHolder;
|
|
|
|
};
|
|
|
|
|
2002-10-11 23:12:31 +00:00
|
|
|
int uprv_initFrequency(UTimer* timer)
|
2002-10-10 01:04:15 +00:00
|
|
|
{
|
|
|
|
return QueryPerformanceFrequency(&timer->placeHolder);
|
|
|
|
}
|
2002-10-11 23:12:31 +00:00
|
|
|
void uprv_start(UTimer* timer)
|
2002-10-10 20:07:17 +00:00
|
|
|
{
|
|
|
|
QueryPerformanceCounter(&timer->start);
|
|
|
|
}
|
2002-10-11 23:12:31 +00:00
|
|
|
double uprv_delta(UTimer* timer1, UTimer* timer2){
|
2002-10-10 01:04:15 +00:00
|
|
|
return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart);
|
|
|
|
}
|
2002-10-11 23:12:31 +00:00
|
|
|
UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
|
2002-10-10 01:04:15 +00:00
|
|
|
return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
struct UTimer{
|
|
|
|
struct timeval start;
|
2002-10-10 20:07:17 +00:00
|
|
|
struct timeval placeHolder;
|
2002-10-10 01:33:59 +00:00
|
|
|
};
|
2002-10-10 01:04:15 +00:00
|
|
|
|
2002-12-06 23:53:00 +00:00
|
|
|
int32_t uprv_initFrequency(UTimer* /*timer*/)
|
2002-10-10 01:04:15 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2002-10-11 23:12:31 +00:00
|
|
|
void uprv_start(UTimer* timer)
|
2002-10-10 01:33:59 +00:00
|
|
|
{
|
2002-10-10 20:07:17 +00:00
|
|
|
gettimeofday(&timer->start, 0);
|
2002-10-10 01:33:59 +00:00
|
|
|
}
|
2002-10-11 23:12:31 +00:00
|
|
|
double uprv_delta(UTimer* timer1, UTimer* timer2){
|
2002-10-10 01:04:15 +00:00
|
|
|
double t1, t2;
|
|
|
|
|
2002-10-10 20:07:17 +00:00
|
|
|
t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000);
|
|
|
|
t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000);
|
|
|
|
return (t2-t1);
|
2002-10-10 01:04:15 +00:00
|
|
|
}
|
2002-12-06 23:53:00 +00:00
|
|
|
UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
|
2002-10-10 01:04:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
/**
|
|
|
|
* Intializes the timer with the current time
|
|
|
|
*
|
|
|
|
* @param timer A pointer to UTimer struct to recieve the current time
|
|
|
|
*/
|
2006-07-29 01:44:45 +00:00
|
|
|
static U_INLINE void U_EXPORT2
|
2002-10-10 01:04:15 +00:00
|
|
|
utimer_getTime(UTimer* timer){
|
|
|
|
uprv_initFrequency(timer);
|
|
|
|
uprv_start(timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the difference in times between timer1 and timer2 by subtracting
|
|
|
|
* timer1's time from timer2's time
|
|
|
|
*
|
|
|
|
* @param timer1 A pointer to UTimer struct to be used as starting time
|
|
|
|
* @param timer2 A pointer to UTimer struct to be used as end time
|
|
|
|
* @return Time in seconds
|
|
|
|
*/
|
2006-07-29 01:44:45 +00:00
|
|
|
static U_INLINE double U_EXPORT2
|
2002-10-10 01:04:15 +00:00
|
|
|
utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){
|
|
|
|
if(uprv_compareFrequency(timer1,timer2)){
|
2002-10-10 20:07:17 +00:00
|
|
|
return uprv_delta(timer1,timer2);
|
2002-10-10 01:04:15 +00:00
|
|
|
}
|
|
|
|
/* got error return -1 */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the time elapsed from the starting time represented by the
|
|
|
|
* UTimer struct pointer passed
|
|
|
|
* @param timer A pointer to UTimer struct to be used as starting time
|
|
|
|
* @return Time elapsed in seconds
|
|
|
|
*/
|
2006-07-29 01:44:45 +00:00
|
|
|
static U_INLINE double U_EXPORT2
|
2002-10-10 01:04:15 +00:00
|
|
|
utimer_getElapsedSeconds(UTimer* timer){
|
|
|
|
UTimer temp;
|
|
|
|
utimer_getTime(&temp);
|
|
|
|
return uprv_delta(timer,&temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Executes the function pointed to for a given time and returns exact time
|
|
|
|
* taken and number of iterations of the loop
|
|
|
|
* @param thresholTimeVal
|
|
|
|
* @param loopCount output param to recieve the number of iterations
|
2002-10-10 20:07:17 +00:00
|
|
|
* @param fn The funtion to be executed
|
|
|
|
* @param param Parameters to be passed to the fn
|
2002-10-10 01:04:15 +00:00
|
|
|
* @return the time elapsed in seconds
|
|
|
|
*/
|
2006-07-29 01:44:45 +00:00
|
|
|
static U_INLINE double U_EXPORT2
|
2002-10-10 01:04:15 +00:00
|
|
|
utimer_loopUntilDone(double thresholdTimeVal,
|
|
|
|
int32_t* loopCount,
|
|
|
|
FuntionToBeTimed fn,
|
|
|
|
void* param){
|
|
|
|
UTimer timer;
|
|
|
|
double currentVal=0;
|
|
|
|
*loopCount = 0;
|
|
|
|
utimer_getTime(&timer);
|
|
|
|
for(;currentVal<thresholdTimeVal;){
|
|
|
|
fn(param);
|
|
|
|
currentVal = utimer_getElapsedSeconds(&timer);
|
2010-07-12 18:03:29 +00:00
|
|
|
(*loopCount)++;
|
2002-10-10 01:04:15 +00:00
|
|
|
}
|
|
|
|
return currentVal;
|
|
|
|
}
|
|
|
|
|
2002-10-10 01:33:59 +00:00
|
|
|
#endif
|
|
|
|
|