ICU-8653 add how expensive is benchmark

X-SVN-Rev: 31120
This commit is contained in:
Steven R. Loomis 2011-12-15 06:16:05 +00:00
parent 1b9190739f
commit 1c9622e92c
10 changed files with 519 additions and 11 deletions

1
.gitattributes vendored
View file

@ -153,6 +153,7 @@ icu4c/source/test/perf/collperf/collperf.vcxproj -text
icu4c/source/test/perf/collperf/collperf.vcxproj.filters -text
icu4c/source/test/perf/convperf/convperf.vcxproj -text
icu4c/source/test/perf/convperf/convperf.vcxproj.filters -text
icu4c/source/test/perf/howExpensiveIs/Makefile.in -text
icu4c/source/test/perf/icuperf2report.xsl -text
icu4c/source/test/perf/normperf/normperf.vcxproj -text
icu4c/source/test/perf/normperf/normperf.vcxproj.filters -text

4
.gitignore vendored
View file

@ -499,6 +499,10 @@ icu4c/source/test/perf/convperf/release
icu4c/source/test/perf/convperf/x64
icu4c/source/test/perf/convperf/x86
icu4c/source/test/perf/dicttrieperf/Makefile
icu4c/source/test/perf/howExpensiveIs/*.d
icu4c/source/test/perf/howExpensiveIs/*.xml
icu4c/source/test/perf/howExpensiveIs/Makefile
icu4c/source/test/perf/howExpensiveIs/howExpensiveIs
icu4c/source/test/perf/ipch
icu4c/source/test/perf/normperf/*.d
icu4c/source/test/perf/normperf/*.o

View file

@ -7510,7 +7510,7 @@ echo "CXXFLAGS=$CXXFLAGS"
# output the Makefiles
ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layout/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/genctd/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layout/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/genctd/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/howExpensiveIs/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@ -8284,6 +8284,7 @@ do
"test/perf/convperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/convperf/Makefile" ;;
"test/perf/normperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/normperf/Makefile" ;;
"test/perf/DateFmtPerf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/DateFmtPerf/Makefile" ;;
"test/perf/howExpensiveIs/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/howExpensiveIs/Makefile" ;;
"test/perf/strsrchperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/strsrchperf/Makefile" ;;
"test/perf/unisetperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/unisetperf/Makefile" ;;
"test/perf/usetperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/usetperf/Makefile" ;;

View file

@ -1262,6 +1262,7 @@ AC_CONFIG_FILES([icudefs.mk \
test/perf/convperf/Makefile \
test/perf/normperf/Makefile \
test/perf/DateFmtPerf/Makefile \
test/perf/howExpensiveIs/Makefile \
test/perf/strsrchperf/Makefile \
test/perf/unisetperf/Makefile \
test/perf/usetperf/Makefile \

View file

@ -1,5 +1,5 @@
## Makefile.in for ICU tests
## Copyright (c) 1999-2010, International Business Machines Corporation and
## Copyright (c) 1999-2011, International Business Machines Corporation and
## others. All Rights Reserved.
## Source directory information
@ -18,7 +18,7 @@ subdir = test/perf
## Files to remove for 'make clean'
CLEANFILES = *~
SUBDIRS = collationperf charperf dicttrieperf normperf ubrkperf unisetperf usetperf ustrperf utfperf utrie2perf DateFmtPerf
SUBDIRS = collationperf charperf dicttrieperf normperf ubrkperf unisetperf usetperf ustrperf utfperf utrie2perf DateFmtPerf howExpensiveIs
# Subdirs that support 'xperf'
XSUBDIRS = DateFmtPerf

View file

@ -0,0 +1,79 @@
## Makefile.in for ICU - test/perf/howExpensiveIs
## Copyright (c) 2001-2011, International Business Machines Corporation and
## others. All Rights Reserved.
## Source directory information
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../..
include $(top_builddir)/icudefs.mk
## Target information
TARGET = howExpensiveIs
## Build directory information
subdir = test/perf/$(TARGET)
## Extra files to remove for 'make clean'
CLEANFILES = *~ $(DEPS)
CPPFLAGS += -I$(top_srcdir)/common -I$(top_builddir)/i18n -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw
LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M)
OBJECTS = howExpensiveIs.o sieve.o
DEPS = $(OBJECTS:.o=.d)
## List of phony targets
.PHONY : all all-local install install-local clean clean-local \
distclean distclean-local dist dist-local check check-local
## Clear suffix list
.SUFFIXES :
## List of standard targets
all: all-local
install: install-local
clean: clean-local
distclean : distclean-local
dist: dist-local
check: all check-local
all-local: $(TARGET)
install-local:
dist-local:
clean-local:
test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
$(RMV) $(OBJECTS) $(TARGET)
distclean-local: clean-local
$(RMV) Makefile
invoke check-local: all-local
ICU_DATA=$${ICU_DATA:-$(top_builddir)/data/} TZ=PST8PDT $(INVOKE) ./$(TARGET) ./howexpensive.xml
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(TARGET) : $(OBJECTS)
$(LINK.cc) -o $@ $^ $(LIBS)
$(POST_BUILD_STEP)
ifeq (,$(MAKECMDGOALS))
-include $(DEPS)
else
ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
ifneq ($(patsubst %install,,$(MAKECMDGOALS)),)
-include $(DEPS)
endif
endif
endif
-include Makefile.local

View file

@ -0,0 +1,182 @@
/*
**********************************************************************
* Copyright (c) 2011,International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#include <stdio.h>
#include "sieve.h"
#include "unicode/utimer.h"
void runTests(void);
FILE *out = NULL;
UErrorCode setupStatus = U_ZERO_ERROR;
int main(int argc, const char* argv[]){
#if U_DEBUG
fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]);
#endif
#if U_DEBUG
{
double m;
double s = uprv_getSieveTime(&m);
fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_TEN_MILLION_TIMES);
}
#endif
if(argc==2) {
out=fopen(argv[1],"w");
if(out==NULL) {
fprintf(stderr,"Err: can't open %s for writing.\n", argv[1]);
return 1;
}
fprintf(out, "<tests icu='%s'>\n", U_ICU_VERSION);
fprintf(out, "<!-- %s -->\n", U_COPYRIGHT_STRING);
} else if(argc>2) {
fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]);
return 1;
}
runTests();
if(out!=NULL) {
fprintf(out, "</tests>\n");
fclose(out);
}
if(U_FAILURE(setupStatus)) {
fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus));
return 1;
}
return 0;
}
class HowExpensiveTest {
public:
virtual ~HowExpensiveTest(){}
protected:
HowExpensiveTest(const char *name, const char *file, int32_t line) : fName(name), fFile(file), fLine(line) {}
protected:
/**
* @return number of iterations
*/
virtual int32_t run() = 0;
virtual void warmup() { run(); }
public:
virtual int32_t runTest(double *subTime) {
UTimer a,b;
utimer_getTime(&a);
int32_t iter = run();
utimer_getTime(&b);
*subTime = utimer_getDeltaSeconds(&a,&b);
return iter;
}
virtual int32_t runTests(double *subTime, double *marginOfError) {
warmup(); /* warmup */
#define ITERATIONS 5
double times[ITERATIONS];
int subIterations = 0;
for(int i=0;i<ITERATIONS;i++) {
subIterations = runTest(&times[i]);
}
*subTime = uprv_getMeanTime(times,ITERATIONS,marginOfError);
return subIterations;
}
public:
const char *fName;
const char *fFile;
int32_t fLine;
int32_t fIterations;
};
void runTestOn(HowExpensiveTest &t) {
fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.fName);
double sieveTime = uprv_getSieveTime(NULL);
double st;
double me;
/* warmup.. */
int32_t iter = t.runTests(&st,&me);
double stn = st/sieveTime;
printf("%s\t%.9f\t%.9f +/- %.9f, @ %d iter\n", t.fName,stn,st,me,iter);
if(out!=NULL) {
fprintf(out, " <test name='%s' standardizedTime='%f' realDuration='%f' marginOfError='%f' iterations='%d' />\n",
t.fName,stn,st,me,iter);
}
}
/* ------------------- test code here --------------------- */
class SieveTest : public HowExpensiveTest {
public:
virtual ~SieveTest(){}
SieveTest():HowExpensiveTest("SieveTest",__FILE__,__LINE__){}
virtual int32_t run(){return 0;} // dummy
int32_t runTest(double *subTime) {
*subTime = uprv_getSieveTime(NULL);
return U_TEN_MILLION_TIMES;
}
virtual int32_t runTests(double *subTime, double *marginOfError) {
*subTime = uprv_getSieveTime(marginOfError);
return U_TEN_MILLION_TIMES;
}
};
/* ------- NumParseTest ------------- */
#include "unicode/unum.h"
/* open and close tests */
#define OCName(svc,ub,testn,suffix,n) testn ## svc ## ub ## suffix ## n
#define OCStr(svc,ub,suffix,n) "Test_" # svc # ub # suffix # n
#define OCRun(svc,ub,suffix) svc ## ub ## suffix
// TODO: run away screaming
#define OpenCloseTest(n, svc,suffix,c,a,d) class OCName(svc,_,Test_,suffix,n) : public HowExpensiveTest { public: OCName(svc,_,Test_,suffix,n)():HowExpensiveTest(OCStr(svc,_,suffix,n),__FILE__,__LINE__) c int32_t run() { int32_t i; for(i=0;i<U_TEN_MILLION_TIMES;i++){ OCRun(svc,_,close) ( OCRun(svc,_,suffix) a ); } return i; } void warmup() { OCRun(svc,_,close) ( OCRun(svc,_,suffix) a); } virtual ~ OCName(svc,_,Test_,suffix,n) () d };
#define QuickTest(n,c,r,d) class n : public HowExpensiveTest { public: n():HowExpensiveTest(#n,__FILE__,__LINE__) c int32_t run() r virtual ~n () d };
// TODO: move, scope.
static UChar pattern[] = { 0x23 }; // '#'
UNumberFormat *NumParseTest_fmt;
// TODO: de-uglify.
QuickTest(NumParseTest,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, "en_US", 0, &setupStatus); },{ int32_t i; static UChar str[] = { 0x31 };double val; for(i=0;i<U_TEN_MILLION_TIMES;i++) { val=unum_parse(NumParseTest_fmt,str,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,"en_US",0,&setupStatus),{})
OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,"en_US",0,&setupStatus),{})
#include "unicode/ucnv.h"
OpenCloseTest(gb18030,ucnv,open,{},("gb18030",&setupStatus),{})
#include "unicode/ures.h"
OpenCloseTest(root,ures,open,{},(NULL,"root",&setupStatus),{})
void runTests() {
{
SieveTest t;
runTestOn(t);
}
{
NumParseTest t;
runTestOn(t);
}
{
Test_unum_opendefault t;
runTestOn(t);
}
{
Test_ucnv_opengb18030 t;
runTestOn(t);
}
{
Test_unum_openpattern t;
runTestOn(t);
}
{
Test_ures_openroot t;
runTestOn(t);
}
}

View file

@ -0,0 +1,205 @@
/*
**********************************************************************
* Copyright (c) 2011,International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#include "unicode/utimer.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "sieve.h"
/* prime number sieve */
U_CAPI double uprv_calcSieveTime() {
#if 1
#define SIEVE_SIZE U_TEN_MILLION_TIMES /* standardized size */
#else
#define SIEVE_SIZE <something_smaller>
#endif
#define SIEVE_PRINT 0
char sieve[SIEVE_SIZE];
UTimer a,b;
int i,k;
utimer_getTime(&a);
for(int j=0;j<SIEVE_SIZE;j++) {
sieve[j]=1;
}
sieve[0]=0;
utimer_getTime(&b);
#if SIEVE_PRINT
printf("init %d: %.9f\n", SIEVE_SIZE,utimer_getDeltaSeconds(&a,&b));
#endif
utimer_getTime(&a);
for(i=2;i<SIEVE_SIZE/2;i++) {
for(k=i*2;k<SIEVE_SIZE;k+=i) {
sieve[k]=0;
}
}
utimer_getTime(&b);
#if SIEVE_PRINT
printf("sieve %d: %.9f\n", SIEVE_SIZE,utimer_getDeltaSeconds(&a,&b));
if(SIEVE_PRINT>0) {
k=0;
for(i=2;i<SIEVE_SIZE && k<SIEVE_PRINT;i++) {
if(sieve[i]) {
printf("%d ", i);
k++;
}
}
puts("");
}
{
k=0;
for(i=0;i<SIEVE_SIZE;i++) {
if(sieve[i]) k++;
}
printf("Primes: %d\n", k);
}
#endif
return utimer_getDeltaSeconds(&a,&b);
}
static int comdoub(const void *aa, const void *bb)
{
const double *a = (const double*)aa;
const double *b = (const double*)bb;
return (*a==*b)?0:((*a<*b)?-1:1);
}
double midpoint(double *times, double i, int n) {
double fl = floor(i);
double ce = ceil(i);
if(ce>=n) ce=n;
if(fl==ce) {
return times[(int)fl];
} else {
return (times[(int)fl]+times[(int)ce])/2;
}
}
double medianof(double *times, int n, int type) {
switch(type) {
case 1:
return midpoint(times,n/4,n);
case 2:
return midpoint(times,n/2,n);
case 3:
return midpoint(times,(n/2)+(n/4),n);
}
return -1;
}
double qs(double *times, int n, double *q1, double *q2, double *q3) {
*q1 = medianof(times,n,1);
*q2 = medianof(times,n,2);
*q3 = medianof(times,n,3);
return *q3-*q1;
}
U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *marginOfError) {
double q1,q2,q3;
int n = timeCount;
/* calculate medians */
qsort(times,n,sizeof(times[0]),comdoub);
double iqr = qs(times,n,&q1,&q2,&q3);
double rangeMin= (q1-(1.5*iqr));
double rangeMax = (q3+(1.5*iqr));
/* Throw out outliers */
int newN = n;
#if U_DEBUG
printf("iqr: %.9f, q1=%.9f, q2=%.9f, q3=%.9f, max=%.9f, n=%d\n", iqr,q1,q2,q3,(double)-1, n);
#endif
for(int i=0;i<newN;i++) {
if(times[i]<rangeMin || times[i]>rangeMax) {
#if U_DEBUG
printf("Knocking out: %.9f from [%.9f:%.9f]\n", times[i], rangeMin, rangeMax);
#endif
times[i--] = times[--newN]; // bring down a new value
}
}
/* if we removed any outliers, recalculate iqr */
if(newN<n) {
#if U_DEBUG
printf("Kicked out %d, retrying..\n", n-newN);
#endif
n = newN;
qsort(times,n,sizeof(times[0]),comdoub);
double iqr = qs(times,n,&q1,&q2,&q3);
rangeMin= (q1-(1.5*iqr));
rangeMax = (q3+(1.5*iqr));
}
/* calculate min/max and mean */
double minTime = times[0];
double maxTime = times[0];
double meanTime = times[0];
for(int i=1;i<n;i++) {
if(minTime>times[i]) minTime=times[i];
if(maxTime<times[i]) maxTime=times[i];
meanTime+=times[i];
}
meanTime /= n;
/* caculate standard deviation */
double sd = 0;
for(int i=0;i<n;i++) {
#if U_DEBUG
printf(" %d: %.9f\n", i, times[i]);
#endif
sd += (times[i]-meanTime)*(times[i]-meanTime);
}
sd = sqrt(sd/(n-1));
#if U_DEBUG
printf("sd: %.9f, mean: %.9f\n", sd, meanTime);
printf("min: %.9f, q1=%.9f, q2=%.9f, q3=%.9f, max=%.9f, n=%d\n", minTime,q1,q2,q3,maxTime, n);
printf("iqr/sd = %.9f\n", iqr/sd);
#endif
/* 1.960 = z sub 0.025 */
*marginOfError = 1.960 * (sd/sqrt(n));
/*printf("Margin of Error = %.4f (95%% confidence)\n", me);*/
return meanTime;
}
UBool calcSieveTime = FALSE;
double meanSieveTime = 0.0;
double meanSieveME = 0.0;
U_CAPI double uprv_getSieveTime(double *marginOfError) {
if(calcSieveTime==FALSE) {
#define SAMPLES 50
double times[SAMPLES];
for(int i=0;i<SAMPLES;i++) {
times[i] = uprv_calcSieveTime();
#if U_DEBUG
printf("#%d/%d: %.9f\n", i,SAMPLES, times[i]);
#endif
}
meanSieveTime = uprv_getMeanTime(times, SAMPLES,&meanSieveME);
calcSieveTime=TRUE;
}
if(marginOfError!=NULL) {
*marginOfError = meanSieveME;
}
return meanSieveTime;
}

View file

@ -0,0 +1,35 @@
/*
**********************************************************************
* Copyright (c) 2011,International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#ifndef SIEVE_H
#define SIEVE_H
#define U_TEN_MILLION_TIMES 10000000
#include "unicode/utypes.h"
/**
* Calculate the standardized sieve time (1 run)
*/
U_INTERNAL double uprv_calcSieveTime(void);
/**
* Calculate the mean time, with margin of error
* @param times array of times (modified/sorted)
* @param timeCount length of array
* @param marginOfError out parameter: gives +/- margin of err at 95% confidence
* @return the mean time, or negative if error/imprecision.
*/
U_INTERNAL double uprv_getMeanTime(double *times, uint32_t timeCount, double *marginOfError);
/**
* Get the standardized sieve time. (Doesn't recalculate if already computed.
* @param marginOfError out parameter: gives +/- margin of error at 95% confidence.
* @return the mean time, or negative if error/imprecision.
*/
U_INTERNAL double uprv_getSieveTime(double *marginOfError);
#endif

View file

@ -167,18 +167,18 @@ typedef void FuntionToBeTimed(void* param);
LARGE_INTEGER placeHolder;
};
int uprv_initFrequency(UTimer* timer)
static int uprv_initFrequency(UTimer* timer)
{
return QueryPerformanceFrequency(&timer->placeHolder);
}
void uprv_start(UTimer* timer)
static void uprv_start(UTimer* timer)
{
QueryPerformanceCounter(&timer->start);
}
double uprv_delta(UTimer* timer1, UTimer* timer2){
static double uprv_delta(UTimer* timer1, UTimer* timer2){
return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart);
}
UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
static UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart);
}
@ -189,22 +189,22 @@ typedef void FuntionToBeTimed(void* param);
struct timeval placeHolder;
};
int32_t uprv_initFrequency(UTimer* /*timer*/)
static int32_t uprv_initFrequency(UTimer* /*timer*/)
{
return 0;
}
void uprv_start(UTimer* timer)
static void uprv_start(UTimer* timer)
{
gettimeofday(&timer->start, 0);
}
double uprv_delta(UTimer* timer1, UTimer* timer2){
static double uprv_delta(UTimer* timer1, UTimer* timer2){
double t1, t2;
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);
}
UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
static UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
return TRUE;
}