From a7c0726f935e65de60da05397045238c3c416e17 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" <srl@icu-project.org> Date: Fri, 14 Oct 2011 19:00:49 +0000 Subject: [PATCH] ICU-8802 improve robustness, also test against stdio sscanf/sprintf for doubles X-SVN-Rev: 30823 --- .../test/perf/DateFmtPerf/DateFmtPerf.cpp | 84 ++++++++++++------- .../test/perf/DateFmtPerf/DateFmtPerf.h | 63 ++++++++++++++ 2 files changed, 117 insertions(+), 30 deletions(-) diff --git a/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.cpp b/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.cpp index afb98212443..909ec6de3a0 100644 --- a/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.cpp +++ b/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.cpp @@ -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"); - - // Perform time recording - double t[5]; - for(int i = 0; i < 5; i++) t[i] = 0; + functions[5] = new StdioNumFmtFunction(100000, "en"); - for(int i = 0; i < 10; i++) - for(int j = 0; j < 5; j++) - t[j] += (functions[j]->time(1, &status) / 10); + // Perform time recording + double t[FUNCTION_COUNT]; + for(int i = 0; i < FUNCTION_COUNT; i++) t[i] = 0; + +#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; -} \ No newline at end of file +} diff --git a/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.h b/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.h index 2a87c43780b..7aeb316418d 100644 --- a/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.h +++ b/icu4c/source/test/perf/DateFmtPerf/DateFmtPerf.h @@ -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 { -- 2.40.0