From 9077d5dc25f9f705d4b75ee7b747665a9dc35ab2 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 17 Sep 2012 19:03:01 +0000 Subject: [PATCH] ICU-9449 Merge in decimal format performance improvements from branch. Improvements to 'howExpensiveIs' benchmark test. Use internal digitlist in Formattable (save mallocs). Enable fastpath by default. Enable internal API "parse all input", returning an error if all input was not consumed. X-SVN-Rev: 32397 --- icu4c/source/common/unicode/uconfig.h | 17 +- icu4c/source/i18n/decimfmt.cpp | 58 +++--- icu4c/source/i18n/digitlst.cpp | 49 ++++- icu4c/source/i18n/digitlst.h | 5 +- icu4c/source/i18n/fmtable.cpp | 6 - icu4c/source/i18n/unicode/fmtable.h | 5 - icu4c/source/samples/date/Makefile.in | 4 +- .../test/perf/howExpensiveIs/Makefile.in | 2 +- .../perf/howExpensiveIs/howExpensiveIs.cpp | 194 ++++++++++++++++-- .../source/test/perf/howExpensiveIs/sieve.cpp | 28 ++- icu4c/source/test/perf/howExpensiveIs/sieve.h | 4 +- icu4c/source/tools/toolutil/udbgutil.cpp | 2 +- 12 files changed, 279 insertions(+), 95 deletions(-) diff --git a/icu4c/source/common/unicode/uconfig.h b/icu4c/source/common/unicode/uconfig.h index 878e346bb9e..8d222614add 100644 --- a/icu4c/source/common/unicode/uconfig.h +++ b/icu4c/source/common/unicode/uconfig.h @@ -385,19 +385,6 @@ # define UCONFIG_NO_SERVICE 0 #endif -/** - * \def UCONFIG_INTERNAL_DIGITLIST - * This switch turns on the fast but binary-incompatible Formattable class with an internal DigitList - * - * @internal - */ -#ifndef UCONFIG_INTERNAL_DIGITLIST -# define UCONFIG_INTERNAL_DIGITLIST 0 -#endif - - - - /** * \def UCONFIG_HAVE_PARSEALLINPUT * This switch turns on the "parse all input" attribute. Binary incompatible. @@ -405,7 +392,7 @@ * @internal */ #ifndef UCONFIG_HAVE_PARSEALLINPUT -# define UCONFIG_HAVE_PARSEALLINPUT 0 +# define UCONFIG_HAVE_PARSEALLINPUT 1 #endif @@ -416,7 +403,7 @@ * @internal */ #ifndef UCONFIG_FORMAT_FASTPATHS_49 -# define UCONFIG_FORMAT_FASTPATHS_49 0 +# define UCONFIG_FORMAT_FASTPATHS_49 1 #endif #endif diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index d3b1becc371..bd156918eba 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -187,9 +187,6 @@ U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { U_CDECL_END - -//#define FMT_DEBUG - #ifdef FMT_DEBUG #include static void _debugout(const char *f, int l, const UnicodeString& s) { @@ -1011,9 +1008,12 @@ void DecimalFormat::handleChanged() { data.fFastpathStatus = kFastpathNO; - if (fGroupingSize!=0) { - debug("No fastpath: fGroupingSize!=0"); // TODO: revisit, should handle ex. up to 999 if groupingsize is 3. - } else if(fGroupingSize2!=0) { + if (fGroupingSize!=0 && isGroupingUsed()) { + debug("No fastpath: fGroupingSize!=0 and grouping is used"); +#ifdef FMT_DEBUG + printf("groupingsize=%d\n", fGroupingSize); +#endif + } else if(fGroupingSize2!=0 && isGroupingUsed()) { debug("No fastpath: fGroupingSize2!=0"); } else if(fUseExponentialNotation) { debug("No fastpath: fUseExponentialNotation"); @@ -1109,7 +1109,7 @@ DecimalFormat::_format(int64_t number, // Slide the number to the start of the output str U_ASSERT(destIdx >= 0); int32_t length = MAX_IDX - destIdx -1; - int32_t prefixLen = appendAffix(appendTo, number, handler, number<0, TRUE); + /*int32_t prefixLen = */ appendAffix(appendTo, number, handler, number<0, TRUE); int32_t maxIntDig = getMaximumIntegerDigits(); int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits @@ -1129,7 +1129,7 @@ DecimalFormat::_format(int64_t number, destlength); handler.addAttribute(kIntegerField, intBegin, appendTo.length()); - int32_t suffixLen = appendAffix(appendTo, number, handler, number<0, FALSE); + /*int32_t suffixLen =*/ appendAffix(appendTo, number, handler, number<0, FALSE); //outputStr[length]=0; @@ -1869,11 +1869,7 @@ void DecimalFormat::parse(const UnicodeString& text, // status is used to record whether a number is infinite. UBool status[fgStatusLength]; -#if UCONFIG_INTERNAL_DIGITLIST DigitList *digits = result.getInternalDigitList(); // get one from the stack buffer -#else - DigitList *digits = new DigitList; -#endif if (digits == NULL) { return; // no way to report error from here. } @@ -1881,9 +1877,6 @@ void DecimalFormat::parse(const UnicodeString& text, if (fCurrencySignCount > fgCurrencySignCountZero) { if (!parseForCurrency(text, parsePosition, *digits, status, currency)) { -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif return; } } else { @@ -1894,9 +1887,6 @@ void DecimalFormat::parse(const UnicodeString& text, parsePosition, *digits, status, currency)) { debug("!subparse(...) - rewind"); parsePosition.setIndex(startIdx); -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif return; } } @@ -1905,9 +1895,6 @@ void DecimalFormat::parse(const UnicodeString& text, if (status[fgStatusInfinite]) { double inf = uprv_getInfinity(); result.setDouble(digits->isPositive() ? inf : -inf); -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif // TODO: set the dl to infinity, and let it fall into the code below. } @@ -2100,7 +2087,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, DBGAPPD(posPrefix); DBGAPPD(posSuffix); debugout(s); - printf("currencyParsing=%d, fFormatWidth=%d, text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, text.length(), negPrefix!=NULL?negPrefix->length():-1); + printf("currencyParsing=%d, fFormatWidth=%d, isParseIntegerOnly=%c text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, (isParseIntegerOnly())?'Y':'N', text.length(), negPrefix!=NULL?negPrefix->length():-1); #endif UBool fastParseOk = false; /* TRUE iff fast parse is OK */ @@ -2117,7 +2104,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, fFormatWidth==0 && // (negPrefix!=NULL&&negPrefix->isEmpty()) || text.length()>0 && - text.length()<20 && + text.length()<32 && (posPrefix==NULL||posPrefix->isEmpty()) && (posSuffix==NULL||posSuffix->isEmpty()) && // (negPrefix==NULL||negPrefix->isEmpty()) && @@ -2131,9 +2118,11 @@ UBool DecimalFormat::subparse(const UnicodeString& text, UChar32 ch = text.char32At(j); const UnicodeString *decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); UChar32 decimalChar = 0; + UBool intOnly = FALSE; int32_t decimalCount = decimalString->countChar32(0,3); if(isParseIntegerOnly()) { decimalChar = 0; // not allowed + intOnly = TRUE; } else if(decimalCount==1) { decimalChar = decimalString->char32At(0); } else if(decimalCount==0) { @@ -2165,6 +2154,8 @@ UBool DecimalFormat::subparse(const UnicodeString& text, parsedNum.append((char)('.'), err); decimalChar=0; // no more decimals. fastParseHadDecimal=TRUE; + } else if(intOnly && !u_isdigit(ch)) { + break; // hit a non-integer. (fall through if integer, to slow parse) } else { digitCount=-1; // fail break; @@ -2172,7 +2163,9 @@ UBool DecimalFormat::subparse(const UnicodeString& text, j+=U16_LENGTH(ch); ch = text.char32At(j); // for next } - if(j==l && (digitCount>0)) { + if( + ((j==l)||intOnly) + && (digitCount>0)) { #ifdef FMT_DEBUG printf("PP -> %d, good = [%s] digitcount=%d, fGroupingSize=%d fGroupingSize2=%d!\n", j, parsedNum.data(), digitCount, fGroupingSize, fGroupingSize2); #endif @@ -2194,6 +2187,15 @@ UBool DecimalFormat::subparse(const UnicodeString& text, #endif parsedNum.clear(); } + } else { +#ifdef FMT_DEBUG + printf("Could not fastpath parse. "); + printf("fFormatWidth=%d ", fFormatWidth); + printf("text.length()=%d ", text.length()); + printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix); + + printf("\n"); +#endif } if(!fastParseOk @@ -2587,7 +2589,13 @@ printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d return FALSE; } #endif - digits.set(parsedNum.toStringPiece(), err); + // uint32_t bits = (fastParseOk?kFastpathOk:0) | + // (fastParseHadDecimal?0:kNoDecimal); + //printf("FPOK=%d, FPHD=%d, bits=%08X\n", fastParseOk, fastParseHadDecimal, bits); + digits.set(parsedNum.toStringPiece(), + err, + 0//bits + ); if (U_FAILURE(err)) { #ifdef FMT_DEBUG diff --git a/icu4c/source/i18n/digitlst.cpp b/icu4c/source/i18n/digitlst.cpp index 39a30cf9378..592b228259f 100644 --- a/icu4c/source/i18n/digitlst.cpp +++ b/icu4c/source/i18n/digitlst.cpp @@ -732,29 +732,56 @@ DigitList::setInteger(int64_t source) * be acceptable for a public API. */ void -DigitList::set(const StringPiece &source, UErrorCode &status) { +DigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) { if (U_FAILURE(status)) { return; } - // Figure out a max number of digits to use during the conversion, and - // resize the number up if necessary. - int32_t numDigits = source.length(); - if (numDigits > fContext.digits) { +#if 0 + if(fastpathBits==(kFastpathOk|kNoDecimal)) { + int32_t size = source.size(); + const char *data = source.data(); + int64_t r = 0; + int64_t m = 1; + // fast parse + while(size>0) { + char ch = data[--size]; + if(ch=='+') { + break; + } else if(ch=='-') { + r = -r; + break; + } else { + int64_t d = ch-'0'; + //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m); + r+=(d)*m; + m *= 10; + } + } + //printf("R=%d\n", r); + set(r); + } else +#endif + { + // Figure out a max number of digits to use during the conversion, and + // resize the number up if necessary. + int32_t numDigits = source.length(); + if (numDigits > fContext.digits) { // fContext.digits == fStorage.getCapacity() decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity()); if (t == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; + status = U_MEMORY_ALLOCATION_ERROR; + return; } fDecNumber = t; fContext.digits = numDigits; - } + } - fContext.status = 0; - uprv_decNumberFromString(fDecNumber, source.data(), &fContext); - if ((fContext.status & DEC_Conversion_syntax) != 0) { + fContext.status = 0; + uprv_decNumberFromString(fDecNumber, source.data(), &fContext); + if ((fContext.status & DEC_Conversion_syntax) != 0) { status = U_DECIMAL_NUMBER_SYNTAX_ERROR; + } } internalClear(); } diff --git a/icu4c/source/i18n/digitlst.h b/icu4c/source/i18n/digitlst.h index 7234afed05e..aa29a14593c 100644 --- a/icu4c/source/i18n/digitlst.h +++ b/icu4c/source/i18n/digitlst.h @@ -68,6 +68,8 @@ template class U_I18N_API MaybeStackHeaderAndArraystackDecimalNum)) { delete fDecimalNum; } else { fDecimalNum->~DigitList(); // destruct, don't deallocate } -#else - delete fDecimalNum; -#endif fDecimalNum = NULL; } @@ -748,7 +744,6 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) { } -#if UCONFIG_INTERNAL_DIGITLIST DigitList * Formattable::getInternalDigitList() { FmtStackData *stackData = (FmtStackData*)fStackData; @@ -760,7 +755,6 @@ Formattable::getInternalDigitList() { } return fDecimalNum; } -#endif // --------------------------------------- void diff --git a/icu4c/source/i18n/unicode/fmtable.h b/icu4c/source/i18n/unicode/fmtable.h index 694e2793256..845122ed2db 100644 --- a/icu4c/source/i18n/unicode/fmtable.h +++ b/icu4c/source/i18n/unicode/fmtable.h @@ -605,13 +605,10 @@ public: */ DigitList *getDigitList() const { return fDecimalNum;} -#if UCONFIG_INTERNAL_DIGITLIST /** * @internal */ DigitList *getInternalDigitList(); -#endif - /** * Adopt, and set value from, a DigitList @@ -652,9 +649,7 @@ private: DigitList *fDecimalNum; -#if UCONFIG_INTERNAL_DIGITLIST char fStackData[128]; // must be big enough for DigitList -#endif Type fType; UnicodeString fBogus; // Bogus string when it's needed. diff --git a/icu4c/source/samples/date/Makefile.in b/icu4c/source/samples/date/Makefile.in index de16093589e..fd2d6282e98 100644 --- a/icu4c/source/samples/date/Makefile.in +++ b/icu4c/source/samples/date/Makefile.in @@ -1,5 +1,5 @@ ## Makefile.in for ICU - samples/date -## Copyright (c) 1999-2011, International Business Machines Corporation and +## Copyright (c) 1999-2012, International Business Machines Corporation and ## others. All Rights Reserved. ## Source directory information @@ -56,7 +56,7 @@ distclean-local: clean-local $(RMV) Makefile check-local: - -$(INVOKE) ./$(TARGET) + -$(INVOKE) ./$(TARGET) $(ICUDATE_OPTS) Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ diff --git a/icu4c/source/test/perf/howExpensiveIs/Makefile.in b/icu4c/source/test/perf/howExpensiveIs/Makefile.in index 190a0c2fdee..2daea675c24 100644 --- a/icu4c/source/test/perf/howExpensiveIs/Makefile.in +++ b/icu4c/source/test/perf/howExpensiveIs/Makefile.in @@ -1,5 +1,5 @@ ## Makefile.in for ICU - test/perf/howExpensiveIs -## Copyright (c) 2001-2011, International Business Machines Corporation and +## Copyright (c) 2001-2012, International Business Machines Corporation and ## others. All Rights Reserved. ## Source directory information diff --git a/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp index fcfd27b3f64..1d15e04a383 100644 --- a/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp +++ b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp @@ -5,11 +5,23 @@ ********************************************************************** */ #include +#include + #include "sieve.h" #include "unicode/utimer.h" #include "udbgutil.h" #include "unicode/ustring.h" #include "unicode/decimfmt.h" +#include "unicode/udat.h" + +#if U_PLATFORM_IMPLEMENTS_POSIX +#include + +static void usage(const char *prog) { + fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog); +} +#endif + void runTests(void); #ifndef ITERATIONS @@ -19,8 +31,24 @@ void runTests(void); FILE *out = NULL; UErrorCode setupStatus = U_ZERO_ERROR; +const char *outName = NULL; +int listmode = 0; +const char *testName = NULL; +const char *progname = NULL; +int errflg = 0; +int testhit = 0; + +int testMatch(const char *aName) { + if(testName==NULL) return 1; + int len = strlen(testName); + if(testName[len-1]=='*') { + return strncmp(testName,aName,len-1); + } else { + return strcmp(testName,aName); + } +} -int main(int argc, const char* argv[]){ +int main(int argc, char * const * argv){ #if U_DEBUG fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]); #endif @@ -32,20 +60,67 @@ int main(int argc, const char* argv[]){ } #endif +#if U_PLATFORM_IMPLEMENTS_POSIX + int c; + extern int optind; + extern char *optarg; + while((c=getopt(argc,argv,"lf:t:")) != EOF) { + switch(c) { + case 'f': + outName = optarg; + break; + case 'l': + listmode++; + break; + case 't': + testName = optarg; + break; + case '?': + errflg++; + } + if(errflg) { + usage(progname); + return 0; + } + } + /* for ( ; optind < argc; optind++) { ... argv[optind] } */ +#else if(argc==2) { - out=fopen(argv[1],"w"); + outName = argv[1]; + } else if(argc>2) { + fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]); + } +#endif + + if(listmode && outName != NULL ) { + fprintf(stderr, "Warning: no output when list mode\n"); + outName=NULL; + } + + if(outName != NULL) { + + + out=fopen(outName,"w"); if(out==NULL) { - fprintf(stderr,"Err: can't open %s for writing.\n", argv[1]); + fprintf(stderr,"Err: can't open %s for writing.\n", outName); return 1; + } else { + fprintf(stderr, "# writing results to %s\n", outName); } fprintf(out, "\n"); 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]); + } else { + fprintf(stderr, "# (no output)\n"); + } + + if(listmode && testName!=NULL) { + fprintf(stderr, "ERR: no -l mode when specific test with -t\n"); + usage(progname); return 1; } + runTests(); @@ -99,7 +174,8 @@ public: fflush(stderr); #endif } - *subTime = uprv_getMeanTime(times,ITERATIONS,marginOfError); + uint32_t iterations = ITERATIONS; + *subTime = uprv_getMeanTime(times,&iterations,marginOfError); return subIterations; } public: @@ -111,7 +187,16 @@ public: void runTestOn(HowExpensiveTest &t) { if(U_FAILURE(setupStatus)) return; // silently - fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName()); + const char *tn = t.getName(); + if(testName!=NULL && testMatch(tn)) return; // skipped. + if(listmode) { + fprintf(stderr, "%s:%d:\t%s\n", t.fFile, t.fLine, t.getName()); + testhit++; + return; + } else { + fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName()); + testhit++; + } double sieveTime = uprv_getSieveTime(NULL); double st; double me; @@ -132,7 +217,7 @@ void runTestOn(HowExpensiveTest &t) { if(out!=NULL) { fprintf(out, " \n", - t.getName(),stn,st,me,iter); + tn,stn,st,me,iter); fflush(out); } } @@ -260,6 +345,34 @@ public: #define DO_AttrNumTest(p,n,x,a,v) { AttrNumTest t(p,n,x,__FILE__,__LINE__,a,v); runTestOn(t); } + +class NOXNumTest : public NumTest +{ +private: + UNumberFormatAttribute fAttr; + int32_t fAttrValue; + char name2[100]; +protected: + virtual const char *getClassName() { + sprintf(name2,"NOXNumTest:%d=%d", fAttr,fAttrValue); + return name2; + } +public: + NOXNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE /*, UNumberFormatAttribute attr, int32_t newValue */) + : NumTest(pat,num,expect,FILE,LINE) /* , + fAttr(attr), + fAttrValue(newValue) */ + { + } + virtual UNumberFormat* initFmt() { + UNumberFormat *fmt = NumTest::initFmt(); + //unum_setAttribute(fmt, fAttr,fAttrValue); + return fmt; + } +}; + +#define DO_NOXNumTest(p,n,x) { NOXNumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } + #define DO_TripleNumTest(p,n,x) DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_YES) \ DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_NO) \ DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE) @@ -485,7 +598,7 @@ public: int32_t run() { int32_t trial; - int i; + int i=0; UnicodeString buf; if(U_SUCCESS(setupStatus)) { for(i=0;i + +QuickTest(RandomTest,{},{timespec ts; ts.tv_sec=rand()%4; int j=U_LOTS_OF_TIMES;while(--j) { ts.tv_nsec=100000+(rand()%10000)*1000000; nanosleep(&ts,NULL); return j;} return U_LOTS_OF_TIMES;},{}) +#endif + 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),{}) #if !UCONFIG_NO_CONVERSION @@ -533,11 +677,24 @@ void runTests() { SieveTest t; runTestOn(t); } +#if 0 + { + RandomTest t; + runTestOn(t); + } +#endif { NullTest t; runTestOn(t); } +#ifndef SKIP_DATEFMT_TESTS + { + DateFormatTestBasic t; + runTestOn(t); + } +#endif + #ifndef SKIP_NUMPARSE_TESTS { // parse tests @@ -548,8 +705,8 @@ void runTests() { DO_NumTest("#","-2 ",-2); DO_NumTest("+#","+2",2); DO_NumTest("#,###.0","2222.0",2222.0); - DO_NumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0); + DO_NumTest("#","123456",123456); // attr #ifdef HAVE_UNUM_MAYBE @@ -567,7 +724,6 @@ void runTests() { } #endif - #ifndef SKIP_NUMFORMAT_TESTS // format tests { @@ -587,7 +743,6 @@ void runTests() { DO_NumFmtStringPieceTest("#.0000","123.4560",spPI); DO_NumFmtStringPieceTest("#.00","123.46",spPI); -#if 1 DO_NumFmtTest("#","0",0.0); DO_NumFmtTest("#","12345",12345); DO_NumFmtTest("#","-2",-2); @@ -600,24 +755,31 @@ void runTests() { DO_NumFmtInt64Test("#","-2",-2); DO_NumFmtInt64Test("+#","+2",2); } -#endif +#ifndef SKIP_NUM_OPEN_TEST { Test_unum_opendefault t; runTestOn(t); } -#if !UCONFIG_NO_CONVERSION { - Test_ucnv_opengb18030 t; + Test_unum_openpattern t; runTestOn(t); } #endif + +#endif /* skip numformat tests */ +#if !UCONFIG_NO_CONVERSION { - Test_unum_openpattern t; + Test_ucnv_opengb18030 t; runTestOn(t); } +#endif { Test_ures_openroot t; runTestOn(t); } + + if(testhit==0) { + fprintf(stderr, "ERROR: no tests matched.\n"); + } } diff --git a/icu4c/source/test/perf/howExpensiveIs/sieve.cpp b/icu4c/source/test/perf/howExpensiveIs/sieve.cpp index ce626d7e7e4..0db512181ba 100644 --- a/icu4c/source/test/perf/howExpensiveIs/sieve.cpp +++ b/icu4c/source/test/perf/howExpensiveIs/sieve.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (c) 2011,International Business Machines + * Copyright (c) 2011-2012,International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -108,9 +108,9 @@ double qs(double *times, int n, double *q1, double *q2, double *q3) { return *q3-*q1; } -U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *marginOfError) { +U_CAPI double uprv_getMeanTime(double *times, uint32_t *timeCount, double *marginOfError) { double q1,q2,q3; - int n = timeCount; + int n = *timeCount; /* calculate medians */ qsort(times,n,sizeof(times[0]),comdoub); @@ -126,18 +126,23 @@ U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *margin for(int i=0;irangeMax) { #if U_DEBUG - printf("Knocking out: %.9f from [%.9f:%.9f]\n", times[i], rangeMin, rangeMax); + printf("Removing outlier: %.9f outside [%.9f:%.9f]\n", times[i], rangeMin, rangeMax); #endif times[i--] = times[--newN]; // bring down a new value } } +#if U_DEBUG + UBool didRemove = false; +#endif /* if we removed any outliers, recalculate iqr */ if(newN