| /* |
| ********************************************************************** |
| * Copyright (c) 2002-2014,International Business Machines |
| * Corporation and others. All Rights Reserved. |
| ********************************************************************** |
| ********************************************************************** |
| */ |
| |
| #ifndef _DATEFMTPERF_H |
| #define _DATEFMTPERF_H |
| |
| |
| #include "unicode/stringpiece.h" |
| #include "unicode/unistr.h" |
| #include "unicode/uperf.h" |
| |
| #include "unicode/dtitvfmt.h" |
| #include "unicode/utypes.h" |
| #include "unicode/datefmt.h" |
| #include "unicode/calendar.h" |
| #include "unicode/uclean.h" |
| #include "unicode/brkiter.h" |
| #include "unicode/numfmt.h" |
| #include "unicode/coll.h" |
| #include "util.h" |
| |
| #include "datedata.h" |
| #include "breakdata.h" |
| #include "collationdata.h" |
| |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <fstream> |
| |
| #include <iostream> |
| using namespace std; |
| |
| // Stubs for Windows API functions when building on UNIXes. |
| // |
| #if U_PLATFORM_USES_ONLY_WIN32_API |
| // do nothing |
| #else |
| #define _UNICODE |
| typedef int DWORD; |
| inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest); |
| #endif |
| |
| class BreakItFunction : public UPerfFunction |
| { |
| private: |
| int num; |
| bool wordIteration; |
| |
| public: |
| |
| BreakItFunction(){num = -1;} |
| BreakItFunction(int a, bool b){num = a; wordIteration = b;} |
| |
| virtual void call(UErrorCode * status) |
| { |
| BreakIterator* boundary; |
| |
| if(wordIteration) |
| { |
| for(int i = 0; i < num; i++) |
| { |
| boundary = BreakIterator::createWordInstance("en", *status); |
| boundary->setText(str); |
| |
| int32_t start = boundary->first(); |
| for (int32_t end = boundary->next(); |
| end != BreakIterator::DONE; |
| start = end, end = boundary->next()) |
| { |
| printTextRange( *boundary, start, end ); |
| } |
| } |
| } |
| |
| else // character iteration |
| { |
| for(int i = 0; i < num; i++) |
| { |
| boundary = BreakIterator::createCharacterInstance(Locale::getUS(), *status); |
| boundary->setText(str); |
| |
| int32_t start = boundary->first(); |
| for (int32_t end = boundary->next(); |
| end != BreakIterator::DONE; |
| start = end, end = boundary->next()) |
| { |
| printTextRange( *boundary, start, end ); |
| } |
| } |
| } |
| |
| |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| if(wordIteration) return 125*num; |
| else return 355*num; |
| } |
| |
| void printUnicodeString(const UnicodeString &s) { |
| char charBuf[1000]; |
| s.extract(0, s.length(), charBuf, sizeof(charBuf)-1, 0); |
| charBuf[sizeof(charBuf)-1] = 0; |
| printf("%s", charBuf); |
| } |
| |
| |
| void printTextRange( BreakIterator& iterator, |
| int32_t start, int32_t end ) |
| { |
| CharacterIterator *strIter = iterator.getText().clone(); |
| UnicodeString s; |
| strIter->getText(s); |
| //printUnicodeString(UnicodeString(s, start, end-start)); |
| //puts(""); |
| delete strIter; |
| } |
| |
| // Print the given string to stdout (for debugging purposes) |
| void uprintf(const UnicodeString &str) { |
| char *buf = 0; |
| int32_t len = str.length(); |
| int32_t bufLen = len + 16; |
| int32_t actualLen; |
| buf = new char[bufLen + 1]; |
| actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion |
| buf[actualLen] = 0; |
| printf("%s", buf); |
| delete[] buf; |
| } |
| |
| }; |
| |
| class DateFmtFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DateFmtFunction() |
| { |
| num = -1; |
| } |
| |
| DateFmtFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* status) |
| { |
| |
| UErrorCode status2 = U_ZERO_ERROR; |
| Calendar *cal; |
| TimeZone *zone; |
| UnicodeString str; |
| UDate date; |
| |
| cal = Calendar::createInstance(status2); |
| check(status2, "Calendar::createInstance"); |
| zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone |
| cal->adoptTimeZone(zone); |
| |
| Locale loc(locale); |
| DateFormat *fmt; |
| fmt = DateFormat::createDateTimeInstance( |
| DateFormat::kShort, DateFormat::kFull, loc); |
| |
| |
| // (dates are imported from datedata.h) |
| for(int j = 0; j < num; j++) |
| for(int i = 0; i < NUM_DATES; i++) |
| { |
| cal->clear(); |
| cal->set(years[i], months[i], days[i]); |
| date = cal->getTime(status2); |
| check(status2, "Calendar::getTime"); |
| |
| fmt->setCalendar(*cal); |
| |
| // Format the date |
| str.remove(); |
| fmt->format(date, str, status2); |
| |
| |
| // Display the formatted date string |
| //uprintf(str); |
| //printf("\n"); |
| |
| } |
| |
| delete fmt; |
| delete cal; |
| //u_cleanup(); |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return NUM_DATES * num; |
| } |
| |
| // Print the given string to stdout (for debugging purposes) |
| void uprintf(const UnicodeString &str) { |
| char *buf = 0; |
| int32_t len = str.length(); |
| int32_t bufLen = len + 16; |
| int32_t actualLen; |
| buf = new char[bufLen + 1]; |
| actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion |
| buf[actualLen] = 0; |
| printf("%s", buf); |
| delete[] buf; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class DateFmtCreateFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DateFmtCreateFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| |
| Locale loc(locale); |
| DateFormat *fmt; |
| // (dates are imported from datedata.h) |
| for(int j = 0; j < num; j++) { |
| fmt = DateFormat::createDateTimeInstance( |
| DateFormat::kShort, DateFormat::kFull, loc); |
| delete fmt; |
| } |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| }; |
| |
| class DateFmtCopyFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DateFmtCopyFunction() |
| { |
| num = -1; |
| } |
| |
| DateFmtCopyFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| Locale loc(locale); |
| UErrorCode status2 = U_ZERO_ERROR; |
| DateFormat *fmt = DateFormat::createDateTimeInstance( |
| DateFormat::kShort, DateFormat::kFull, loc); |
| for(int j = 0; j < num; j++) { |
| Format *cp = fmt->clone(); |
| delete cp; |
| } |
| delete fmt; |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class DIFCreateFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DIFCreateFunction() |
| { |
| num = -1; |
| } |
| |
| DIFCreateFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| UErrorCode status2 = U_ZERO_ERROR; |
| Calendar *cal; |
| TimeZone *zone; |
| |
| cal = Calendar::createInstance(status2); |
| check(status2, "Calendar::createInstance"); |
| zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone |
| cal->adoptTimeZone(zone); |
| |
| Locale loc(locale); |
| UnicodeString skeleton("yMMMMdHms"); |
| |
| for(int j = 0; j < num; j++) { |
| DateIntervalFormat* fmt(DateIntervalFormat::createInstance(skeleton, loc, status2)); |
| delete fmt; |
| } |
| delete cal; |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class TimeZoneCreateFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| TimeZoneCreateFunction() |
| { |
| num = -1; |
| } |
| |
| TimeZoneCreateFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| Locale loc(locale); |
| UnicodeString tzname("UTC"); |
| for(int j = 0; j < num; j++) { |
| TimeZone* tz(TimeZone::createTimeZone(tzname)); |
| delete tz; |
| } |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class DTPatternGeneratorCreateFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DTPatternGeneratorCreateFunction() |
| { |
| num = -1; |
| } |
| |
| DTPatternGeneratorCreateFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| UErrorCode status2 = U_ZERO_ERROR; |
| Locale loc(locale); |
| |
| for(int j = 0; j < num; j++) { |
| DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2)); |
| delete gen; |
| } |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class DTPatternGeneratorCopyFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DTPatternGeneratorCopyFunction() |
| { |
| num = -1; |
| } |
| |
| DTPatternGeneratorCopyFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| UErrorCode status2 = U_ZERO_ERROR; |
| Locale loc(locale); |
| DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2)); |
| |
| for(int j = 0; j < num; j++) { |
| DateTimePatternGenerator *cl = gen->clone(); |
| delete cl; |
| } |
| delete gen; |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class DTPatternGeneratorBestValueFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| DTPatternGeneratorBestValueFunction() |
| { |
| num = -1; |
| } |
| |
| DTPatternGeneratorBestValueFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* /* status */) |
| { |
| UErrorCode status2 = U_ZERO_ERROR; |
| Locale loc(locale); |
| DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2)); |
| UnicodeString skeleton("yMMMMdHms"); |
| |
| for(int j = 0; j < num; j++) { |
| gen->getBestPattern(skeleton, status2); |
| } |
| check(status2, "getBestPattern"); |
| delete gen; |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Verify that a UErrorCode is successful; exit(1) if not |
| void check(UErrorCode& status, const char* msg) { |
| if (U_FAILURE(status)) { |
| printf("ERROR: %s (%s)\n", u_errorName(status), msg); |
| exit(1); |
| } |
| } |
| |
| }; |
| |
| class NumFmtFunction : public UPerfFunction |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| public: |
| |
| NumFmtFunction() |
| { |
| num = -1; |
| } |
| |
| NumFmtFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| } |
| |
| virtual void call(UErrorCode* status2) |
| { |
| Locale loc(locale); |
| UErrorCode status = U_ZERO_ERROR; |
| |
| // Create a number formatter for the locale |
| NumberFormat *fmt = NumberFormat::createInstance(loc, status); |
| |
| // Parse a string. The string uses the digits '0' through '9' |
| // and the decimal separator '.', standard in the US locale |
| |
| for(int i = 0; i < num; i++) |
| { |
| UnicodeString str("9876543210.123"); |
| Formattable result; |
| fmt->parse(str, result, status); |
| |
| //uprintf(formattableToString(result)); |
| //printf("\n"); |
| |
| // Take the number parsed above, and use the formatter to |
| // format it. |
| str.remove(); // format() will APPEND to this string |
| fmt->format(result, str, status); |
| |
| //uprintf(str); |
| //printf("\n"); |
| } |
| |
| delete fmt; // Release the storage used by the formatter |
| } |
| |
| enum { |
| U_SPACE=0x20, |
| U_DQUOTE=0x22, |
| U_COMMA=0x2c, |
| U_LEFT_SQUARE_BRACKET=0x5b, |
| U_BACKSLASH=0x5c, |
| U_RIGHT_SQUARE_BRACKET=0x5d, |
| U_SMALL_U=0x75 |
| }; |
| |
| // Create a display string for a formattable |
| UnicodeString formattableToString(const Formattable& f) { |
| switch (f.getType()) { |
| case Formattable::kDate: |
| // TODO: Finish implementing this |
| return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD"); |
| case Formattable::kDouble: |
| { |
| char buf[256]; |
| sprintf(buf, "%gD", f.getDouble()); |
| return UnicodeString(buf, ""); |
| } |
| case Formattable::kLong: |
| case Formattable::kInt64: |
| { |
| char buf[256]; |
| sprintf(buf, "%ldL", f.getLong()); |
| return UnicodeString(buf, ""); |
| } |
| case Formattable::kString: |
| return UnicodeString((UChar)U_DQUOTE).append(f.getString()).append((UChar)U_DQUOTE); |
| case Formattable::kArray: |
| { |
| int32_t i, count; |
| const Formattable* array = f.getArray(count); |
| UnicodeString result((UChar)U_LEFT_SQUARE_BRACKET); |
| for (i=0; i<count; ++i) { |
| if (i > 0) { |
| (result += (UChar)U_COMMA) += (UChar)U_SPACE; |
| } |
| result += formattableToString(array[i]); |
| } |
| result += (UChar)U_RIGHT_SQUARE_BRACKET; |
| return result; |
| } |
| default: |
| return UNICODE_STRING_SIMPLE("INVALID_Formattable"); |
| } |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| |
| // Print the given string to stdout using the UTF-8 converter (for debugging purposes only) |
| void uprintf(const UnicodeString &str) { |
| char stackBuffer[100]; |
| char *buf = 0; |
| |
| int32_t bufLen = str.extract(0, 0x7fffffff, stackBuffer, sizeof(stackBuffer), "UTF-8"); |
| if(bufLen < sizeof(stackBuffer)) { |
| buf = stackBuffer; |
| } else { |
| buf = new char[bufLen + 1]; |
| bufLen = str.extract(0, 0x7fffffff, buf, bufLen + 1, "UTF-8"); |
| } |
| printf("%s", buf); |
| if(buf != stackBuffer) { |
| delete[] buf; |
| } |
| } |
| }; |
| |
| |
| |
| #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 |
| { |
| |
| private: |
| int num; |
| char locale[25]; |
| UnicodeString *collation_strings; |
| |
| /** |
| * Unescape the strings |
| */ |
| void init() { |
| uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]); |
| collation_strings = new UnicodeString[listSize]; |
| for(uint32_t k=0;k<listSize;k++) { |
| collation_strings[k] = collation_strings_escaped[k].unescape(); |
| } |
| UnicodeString shorty((UChar32)0x12345); |
| } |
| public: |
| |
| CollationFunction() |
| { |
| num = -1; |
| |
| init(); |
| } |
| |
| ~CollationFunction() { |
| delete [] collation_strings; |
| } |
| |
| CollationFunction(int a, const char* loc) |
| { |
| num = a; |
| strcpy(locale, loc); |
| init(); |
| } |
| |
| virtual void call(UErrorCode* status2) |
| { |
| uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]); |
| UErrorCode status = U_ZERO_ERROR; |
| Collator *coll = Collator::createInstance(Locale(locale), status); |
| |
| for(int k = 0; k < num; k++) |
| { |
| uint32_t i, j; |
| for(i=listSize-1; i>=1; i--) { |
| for(j=0; j<i; j++) { |
| if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) { |
| //cout << "Success!" << endl; |
| } |
| } |
| } |
| } |
| delete coll; |
| } |
| |
| virtual long getOperationsPerIteration() |
| { |
| return num; |
| } |
| }; |
| |
| class DateFormatPerfTest : public UPerfTest |
| { |
| private: |
| |
| public: |
| |
| DateFormatPerfTest(int32_t argc, const char* argv[], UErrorCode& status); |
| ~DateFormatPerfTest(); |
| virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par); |
| |
| UPerfFunction* DateFmt250(); |
| UPerfFunction* DateFmt10000(); |
| UPerfFunction* DateFmt100000(); |
| UPerfFunction* DateFmtCreate250(); |
| UPerfFunction* DateFmtCreate10000(); |
| UPerfFunction* DateFmtCopy250(); |
| UPerfFunction* DateFmtCopy10000(); |
| UPerfFunction* BreakItWord250(); |
| UPerfFunction* BreakItWord10000(); |
| UPerfFunction* BreakItChar250(); |
| UPerfFunction* BreakItChar10000(); |
| UPerfFunction* NumFmt10000(); |
| UPerfFunction* NumFmt100000(); |
| UPerfFunction* Collation10000(); |
| UPerfFunction* Collation100000(); |
| UPerfFunction* DIFCreate250(); |
| UPerfFunction* DIFCreate10000(); |
| UPerfFunction* TimeZoneCreate250(); |
| UPerfFunction* TimeZoneCreate10000(); |
| UPerfFunction* DTPatternGeneratorCreate250(); |
| UPerfFunction* DTPatternGeneratorCreate10000(); |
| UPerfFunction* DTPatternGeneratorCopy250(); |
| UPerfFunction* DTPatternGeneratorCopy10000(); |
| UPerfFunction* DTPatternGeneratorBestValue250(); |
| UPerfFunction* DTPatternGeneratorBestValue10000(); |
| }; |
| |
| #endif // DateFmtPerf |