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
# 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.
* @internal
*/
#ifndef UCONFIG_HAVE_PARSEALLINPUT
-# define UCONFIG_HAVE_PARSEALLINPUT 0
+# define UCONFIG_HAVE_PARSEALLINPUT 1
#endif
* @internal
*/
#ifndef UCONFIG_FORMAT_FASTPATHS_49
-# define UCONFIG_FORMAT_FASTPATHS_49 0
+# define UCONFIG_FORMAT_FASTPATHS_49 1
#endif
#endif
U_CDECL_END
-
-//#define FMT_DEBUG
-
#ifdef FMT_DEBUG
#include <stdio.h>
static void _debugout(const char *f, int l, const UnicodeString& s) {
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");
// 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
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;
// 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.
}
if (fCurrencySignCount > fgCurrencySignCountZero) {
if (!parseForCurrency(text, parsePosition, *digits,
status, currency)) {
-#if !UCONFIG_INTERNAL_DIGITLIST
- delete digits;
-#endif
return;
}
} else {
parsePosition, *digits, status, currency)) {
debug("!subparse(...) - rewind");
parsePosition.setIndex(startIdx);
-#if !UCONFIG_INTERNAL_DIGITLIST
- delete digits;
-#endif
return;
}
}
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.
}
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 */
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()) &&
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) {
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;
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
#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
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
* 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();
}
enum EStackMode { kOnStack };
+enum EFastpathBits { kFastpathOk = 1, kNoDecimal = 2 };
+
/**
* Digit List is actually a Decimal Floating Point number.
* The original implementation has been replaced by a thin wrapper onto a
* Utility routine to set the value of the digit list from a decimal number
* string.
* @param source The value to be set. The string must be nul-terminated.
+ * @param fastpathBits special flags for fast parsing
*/
- void set(const StringPiece &source, UErrorCode &status);
+ void set(const StringPiece &source, UErrorCode &status, uint32_t fastpathBits = 0);
/**
* Multiply this = this * arg
delete fDecimalStr;
fDecimalStr = NULL;
-#if UCONFIG_INTERNAL_DIGITLIST
FmtStackData *stackData = (FmtStackData*)fStackData;
if(fDecimalNum != &(stackData->stackDecimalNum)) {
delete fDecimalNum;
} else {
fDecimalNum->~DigitList(); // destruct, don't deallocate
}
-#else
- delete fDecimalNum;
-#endif
fDecimalNum = NULL;
}
}
-#if UCONFIG_INTERNAL_DIGITLIST
DigitList *
Formattable::getInternalDigitList() {
FmtStackData *stackData = (FmtStackData*)fStackData;
}
return fDecimalNum;
}
-#endif
// ---------------------------------------
void
*/
DigitList *getDigitList() const { return fDecimalNum;}
-#if UCONFIG_INTERNAL_DIGITLIST
/**
* @internal
*/
DigitList *getInternalDigitList();
-#endif
-
/**
* Adopt, and set value from, a DigitList
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.
## 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
$(RMV) Makefile
check-local:
- -$(INVOKE) ./$(TARGET)
+ -$(INVOKE) ./$(TARGET) $(ICUDATE_OPTS)
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
## 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
**********************************************************************
*/
#include <stdio.h>
+#include <string.h>
+
#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 <unistd.h>
+
+static void usage(const char *prog) {
+ fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog);
+}
+#endif
+
void runTests(void);
#ifndef ITERATIONS
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
}
#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, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
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]);
+ } 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();
fflush(stderr);
#endif
}
- *subTime = uprv_getMeanTime(times,ITERATIONS,marginOfError);
+ uint32_t iterations = ITERATIONS;
+ *subTime = uprv_getMeanTime(times,&iterations,marginOfError);
return subIterations;
}
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;
if(out!=NULL) {
fprintf(out, " <test name=\"%s\" standardizedTime=\"%f\" realDuration=\"%f\" marginOfError=\"%f\" iterations=\"%d\" />\n",
- t.getName(),stn,st,me,iter);
+ tn,stn,st,me,iter);
fflush(out);
}
}
#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)
int32_t run() {
int32_t trial;
- int i;
+ int i=0;
UnicodeString buf;
if(U_SUCCESS(setupStatus)) {
for(i=0;i<U_LOTS_OF_TIMES;i++){
QuickTest(NumParseTestdot,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, "en_US", 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strdot,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
QuickTest(NumParseTestspc,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, "en_US", 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strspc,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
QuickTest(NumParseTestgrp,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, "en_US", 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strgrp,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
+
QuickTest(NumParseTestbeng,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, "en_US", 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strbeng,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
+UDateFormat *DateFormatTest_fmt = NULL;
+UDate sometime = 100000000.0;
+UChar onekbuf[1024];
+const int32_t onekbuf_len = sizeof(onekbuf)/sizeof(onekbuf[0]);
+
+
+QuickTest(DateFormatTestBasic, \
+ { \
+ DateFormatTest_fmt = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &setupStatus); \
+ }, \
+ { \
+ int i; \
+ for(i=0;i<U_LOTS_OF_TIMES;i++) \
+ { \
+ udat_format(DateFormatTest_fmt, sometime, onekbuf, onekbuf_len, NULL, &setupStatus); \
+ } \
+ return i; \
+ }, \
+ { \
+ udat_close(DateFormatTest_fmt); \
+ } \
+ )
+
QuickTest(NullTest,{},{int j=U_LOTS_OF_TIMES;while(--j);return U_LOTS_OF_TIMES;},{})
+
+#if 0
+#include <time.h>
+
+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
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
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
}
#endif
-
#ifndef SKIP_NUMFORMAT_TESTS
// format tests
{
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);
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");
+ }
}
/*
**********************************************************************
- * Copyright (c) 2011,International Business Machines
+ * Copyright (c) 2011-2012,International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
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);
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);
+ 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<n) {
#if U_DEBUG
- printf("Kicked out %d, retrying..\n", n-newN);
+ didRemove = true;
+ printf("removed %d outlier(s), recalculating IQR..\n", n-newN);
#endif
n = newN;
+ *timeCount = n;
qsort(times,n,sizeof(times[0]),comdoub);
double iqr = qs(times,n,&q1,&q2,&q3);
double sd = 0;
for(int i=0;i<n;i++) {
#if U_DEBUG
- printf(" %d: %.9f\n", i, times[i]);
+ if(didRemove) {
+ printf("recalc %d/%d: %.9f\n", i, n, times[i]);
+ }
#endif
sd += (times[i]-meanTime)*(times[i]-meanTime);
}
- sd = sqrt(sd/(n-1));
+ sd = sqrt(sd/((double)n-1.0));
#if U_DEBUG
printf("sd: %.9f, mean: %.9f\n", sd, meanTime);
#endif
/* 1.960 = z sub 0.025 */
- *marginOfError = 1.960 * (sd/sqrt(n));
+ *marginOfError = 1.960 * (sd/sqrt((double)n));
/*printf("Margin of Error = %.4f (95%% confidence)\n", me);*/
return meanTime;
U_CAPI double uprv_getSieveTime(double *marginOfError) {
if(calcSieveTime==FALSE) {
#define SAMPLES 50
+ uint32_t samples = SAMPLES;
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]);
+ printf("sieve: %d/%d: %.9f\n", i,SAMPLES, times[i]);
#endif
}
- meanSieveTime = uprv_getMeanTime(times, SAMPLES,&meanSieveME);
+ meanSieveTime = uprv_getMeanTime(times, &samples,&meanSieveME);
calcSieveTime=TRUE;
}
if(marginOfError!=NULL) {
/**
* Calculate the mean time, with margin of error
* @param times array of times (modified/sorted)
- * @param timeCount length of array
+ * @param timeCount length of array - on return, how many remain after throwing out outliers
* @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);
+U_INTERNAL double uprv_getMeanTime(double *times, uint32_t *timeCount, double *marginOfError);
/**
* Get the standardized sieve time. (Doesn't recalculate if already computed.
#if defined (CYGWINMSVC)
{ "build.cygwinmsvc", paramInteger, "b", 1},
#endif
- { "uconfig.internal_digitlist", paramInteger, "b", UCONFIG_INTERNAL_DIGITLIST},
+ { "uconfig.internal_digitlist", paramInteger, "b", 1}, /* always 1 */
{ "uconfig.have_parseallinput", paramInteger, "b", UCONFIG_HAVE_PARSEALLINPUT},
{ "uconfig.format_fastpaths_49",paramInteger, "b", UCONFIG_FORMAT_FASTPATHS_49},