ICU-8802 improve robustness, also test against stdio sscanf/sprintf for doubles

X-SVN-Rev: 30823
This commit is contained in:
Steven R. Loomis 2011-10-14 19:00:49 +00:00
parent c3a95aefe9
commit a7c0726f93
2 changed files with 116 additions and 29 deletions

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2010,International Business Machines
* Copyright (c) 2002-2011,International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
**********************************************************************
@ -33,11 +33,11 @@ UPerfFunction* DateFormatPerfTest::runIndexedTest(int32_t index, UBool exec,cons
switch (index) {
TESTCASE(0,DateFmt250);
TESTCASE(1,DateFmt10000);
TESTCASE(2,DateFmt100000);
TESTCASE(2,DateFmt100000);
TESTCASE(3,BreakItWord250);
TESTCASE(4,BreakItWord10000);
TESTCASE(5,BreakItChar250);
TESTCASE(6,BreakItChar10000);
TESTCASE(4,BreakItWord10000);
TESTCASE(5,BreakItChar250);
TESTCASE(6,BreakItChar10000);
TESTCASE(7,NumFmt10000);
TESTCASE(8,NumFmt100000);
TESTCASE(9,Collation10000);
@ -122,49 +122,73 @@ int main(int argc, const char* argv[]){
cout << "ICU version - " << U_ICU_VERSION << endl;
UErrorCode status = U_ZERO_ERROR;
#define FUNCTION_COUNT 6
// Declare functions
UPerfFunction *functions[5];
UPerfFunction *functions[FUNCTION_COUNT];
functions[0] = new DateFmtFunction(40, "en");
functions[1] = new BreakItFunction(10000, true); // breakIterator word
functions[2] = new BreakItFunction(10000, false); // breakIterator char
functions[3] = new NumFmtFunction(100000, "en");
functions[4] = new CollationFunction(400, "en");
functions[5] = new StdioNumFmtFunction(100000, "en");
// Perform time recording
double t[5];
for(int i = 0; i < 5; i++) t[i] = 0;
double t[FUNCTION_COUNT];
for(int i = 0; i < FUNCTION_COUNT; i++) t[i] = 0;
for(int i = 0; i < 10; i++)
for(int j = 0; j < 5; j++)
t[j] += (functions[j]->time(1, &status) / 10);
#define ITER_COUNT 10
#ifdef U_DEBUG
cout << "Doing " << ITER_COUNT << " iterations:" << endl;
cout << "__________| Running...\r";
cout.flush();
#endif
for(int i = 0; i < ITER_COUNT; i++) {
#ifdef U_DEBUG
cout << '*' << flush;
#endif
for(int j = 0; U_SUCCESS(status)&& j < FUNCTION_COUNT; j++)
t[j] += (functions[j]->time(1, &status) / ITER_COUNT);
}
#ifdef U_DEBUG
cout << " Done " << endl;
#endif
if(U_SUCCESS(status)) {
// Output results as .xml
ofstream out;
out.open(argv[2]);
// Output results as .xml
ofstream out;
out.open(argv[2]);
out << "<perfTestResults icu=\"c\" version=\"" << U_ICU_VERSION << "\">" << endl;
out << "<perfTestResults icu=\"c\" version=\"" << U_ICU_VERSION << "\">" << endl;
for(int i = 0; i < 5; i++)
{
out << " <perfTestResult" << endl;
out << " test=\"";
switch(i)
for(int i = 0; i < FUNCTION_COUNT; i++)
{
out << " <perfTestResult" << endl;
out << " test=\"";
switch(i)
{
case 0: out << "DateFormat"; break;
case 1: out << "BreakIterator Word"; break;
case 2: out << "BreakIterator Char"; break;
case 3: out << "NumbFormat"; break;
case 4: out << "Collation"; break;
case 5: out << "StdioNumbFormat"; break;
default: out << "Unknown " << i; break;
}
out << "\"" << endl;
out << " iterations=\"" << functions[i]->getOperationsPerIteration() << "\"" << endl;
out << " time=\"" << t[i] << "\" />" << endl;
}
out << "\"" << endl;
int iter = 10000;
if(i > 2) iter = 100000;
out << " iterations=\"" << iter << "\"" << endl;
out << " time=\"" << t[i] << "\" />" << endl;
out << "</perfTestResults>" << endl;
out.close();
cout << " Wrote to " << argv[2] << endl;
}
if(U_FAILURE(status)) {
cout << "Error! " << u_errorName(status) << endl;
return 1;
}
out << "</perfTestResults>" << endl;
out.close();
return 0;
}
@ -190,4 +214,4 @@ int main(int argc, const char* argv[]){
cout << "done!" << endl;
return 0;
}
}

View File

@ -356,6 +356,69 @@ public:
}
};
#define NUM_STRING "9876543210.123"
#define NUM_NUM 9876543210.123
class StdioNumFmtFunction : public UPerfFunction
{
private:
int num;
char locale[25];
public:
StdioNumFmtFunction()
{
num = -1;
}
StdioNumFmtFunction(int a, const char* loc)
{
num = a;
strcpy(locale, loc);
}
virtual void call(UErrorCode* status2)
{
Locale loc(locale);
UErrorCode status = U_ZERO_ERROR;
// Parse a string. The string uses the digits '0' through '9'
// and the decimal separator '.', standard in the US locale
double result;
char outbuf[500];
const char *str = NUM_STRING;
for(int i = 0; i < num; i++)
{
if(sscanf(str, "%lg", &result)!=1) {
cout << "Failed Stdio: failed to sscanf" << endl;
*status2 = U_PARSE_ERROR;
return;
}
sprintf(outbuf, "%lg", result);
}
if(result!=NUM_NUM) {
cout << "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM << " got " << result << endl;
*status2 = U_PARSE_ERROR;
}
if(strcmp(str,NUM_STRING)) {
cout << "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING << " got " << str << endl;
*status2 = U_PARSE_ERROR;
}
}
virtual long getOperationsPerIteration()
{
return num;
}
};
class CollationFunction : public UPerfFunction
{