From 1c9622e92c6a4883abc4efbb957a318a40b5ee3b Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 15 Dec 2011 06:16:05 +0000 Subject: [PATCH] ICU-8653 add how expensive is benchmark X-SVN-Rev: 31120 --- .gitattributes | 1 + .gitignore | 4 + icu4c/source/configure | 3 +- icu4c/source/configure.in | 1 + icu4c/source/test/perf/Makefile.in | 4 +- .../test/perf/howExpensiveIs/Makefile.in | 79 +++++++ .../perf/howExpensiveIs/howExpensiveIs.cpp | 182 ++++++++++++++++ .../source/test/perf/howExpensiveIs/sieve.cpp | 205 ++++++++++++++++++ icu4c/source/test/perf/howExpensiveIs/sieve.h | 35 +++ icu4c/source/tools/ctestfw/unicode/utimer.h | 16 +- 10 files changed, 519 insertions(+), 11 deletions(-) create mode 100644 icu4c/source/test/perf/howExpensiveIs/Makefile.in create mode 100644 icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp create mode 100644 icu4c/source/test/perf/howExpensiveIs/sieve.cpp create mode 100644 icu4c/source/test/perf/howExpensiveIs/sieve.h diff --git a/.gitattributes b/.gitattributes index 7f3b5691766..c0bb002ff5c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore index f2c6c3f4169..7c446950990 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/icu4c/source/configure b/icu4c/source/configure index 0908c88d064..7901aacff1d 100755 --- a/icu4c/source/configure +++ b/icu4c/source/configure @@ -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" ;; diff --git a/icu4c/source/configure.in b/icu4c/source/configure.in index b4a8e36d7ce..39bc55af261 100644 --- a/icu4c/source/configure.in +++ b/icu4c/source/configure.in @@ -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 \ diff --git a/icu4c/source/test/perf/Makefile.in b/icu4c/source/test/perf/Makefile.in index f3db0d5367d..049ca587280 100644 --- a/icu4c/source/test/perf/Makefile.in +++ b/icu4c/source/test/perf/Makefile.in @@ -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 diff --git a/icu4c/source/test/perf/howExpensiveIs/Makefile.in b/icu4c/source/test/perf/howExpensiveIs/Makefile.in new file mode 100644 index 00000000000..755b3a68d99 --- /dev/null +++ b/icu4c/source/test/perf/howExpensiveIs/Makefile.in @@ -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 diff --git a/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp new file mode 100644 index 00000000000..2b0184eab23 --- /dev/null +++ b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp @@ -0,0 +1,182 @@ +/* + ********************************************************************** + * Copyright (c) 2011,International Business Machines + * Corporation and others. All Rights Reserved. + ********************************************************************** + */ +#include +#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, "\n", U_ICU_VERSION); + fprintf(out, "\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, "\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\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 +#include +#include + +#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 +#endif + +#define SIEVE_PRINT 0 + + char sieve[SIEVE_SIZE]; + UTimer a,b; + int i,k; + + utimer_getTime(&a); + for(int j=0;j0) { + k=0; + for(i=2;i=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;irangeMax) { +#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(newNtimes[i]) minTime=times[i]; + if(maxTimeplaceHolder); } - 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; } -- 2.40.0