2 ***********************************************************************
3 * Copyright (C) 2016 and later: Unicode, Inc. and others.
4 * License & terms of use: http://www.unicode.org/copyright.html#License
5 ***********************************************************************
6 ***********************************************************************
7 * Copyright (c) 2002-2016,International Business Machines
8 * Corporation and others. All Rights Reserved.
9 ***********************************************************************
10 ***********************************************************************
13 #ifndef _DATEFMTPERF_H
14 #define _DATEFMTPERF_H
17 #include "unicode/stringpiece.h"
18 #include "unicode/unistr.h"
19 #include "unicode/uperf.h"
21 #include "unicode/dtitvfmt.h"
22 #include "unicode/utypes.h"
23 #include "unicode/datefmt.h"
24 #include "unicode/calendar.h"
25 #include "unicode/uclean.h"
26 #include "unicode/brkiter.h"
27 #include "unicode/numfmt.h"
28 #include "unicode/coll.h"
32 #include "breakdata.h"
33 #include "collationdata.h"
43 // Stubs for Windows API functions when building on UNIXes.
45 #if U_PLATFORM_USES_ONLY_WIN32_API
50 inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
53 class BreakItFunction : public UPerfFunction
61 BreakItFunction(){num = -1;}
62 BreakItFunction(int a, bool b){num = a; wordIteration = b;}
64 virtual void call(UErrorCode * status)
66 BreakIterator* boundary;
70 for(int i = 0; i < num; i++)
72 boundary = BreakIterator::createWordInstance("en", *status);
73 boundary->setText(str);
75 int32_t start = boundary->first();
76 for (int32_t end = boundary->next();
77 end != BreakIterator::DONE;
78 start = end, end = boundary->next())
80 printTextRange( *boundary, start, end );
85 else // character iteration
87 for(int i = 0; i < num; i++)
89 boundary = BreakIterator::createCharacterInstance(Locale::getUS(), *status);
90 boundary->setText(str);
92 int32_t start = boundary->first();
93 for (int32_t end = boundary->next();
94 end != BreakIterator::DONE;
95 start = end, end = boundary->next())
97 printTextRange( *boundary, start, end );
105 virtual long getOperationsPerIteration()
107 if(wordIteration) return 125*num;
111 void printUnicodeString(const UnicodeString &s) {
113 s.extract(0, s.length(), charBuf, sizeof(charBuf)-1, 0);
114 charBuf[sizeof(charBuf)-1] = 0;
115 printf("%s", charBuf);
119 void printTextRange( BreakIterator& iterator,
120 int32_t start, int32_t end )
122 CharacterIterator *strIter = iterator.getText().clone();
125 //printUnicodeString(UnicodeString(s, start, end-start));
130 // Print the given string to stdout (for debugging purposes)
131 void uprintf(const UnicodeString &str) {
133 int32_t len = str.length();
134 int32_t bufLen = len + 16;
136 buf = new char[bufLen + 1];
137 actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
145 class DateFmtFunction : public UPerfFunction
158 DateFmtFunction(int a, const char* loc)
164 virtual void call(UErrorCode* status)
167 UErrorCode status2 = U_ZERO_ERROR;
173 cal = Calendar::createInstance(status2);
174 check(status2, "Calendar::createInstance");
175 zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
176 cal->adoptTimeZone(zone);
180 fmt = DateFormat::createDateTimeInstance(
181 DateFormat::kShort, DateFormat::kFull, loc);
184 // (dates are imported from datedata.h)
185 for(int j = 0; j < num; j++)
186 for(int i = 0; i < NUM_DATES; i++)
189 cal->set(years[i], months[i], days[i]);
190 date = cal->getTime(status2);
191 check(status2, "Calendar::getTime");
193 fmt->setCalendar(*cal);
197 fmt->format(date, str, status2);
200 // Display the formatted date string
211 virtual long getOperationsPerIteration()
213 return NUM_DATES * num;
216 // Print the given string to stdout (for debugging purposes)
217 void uprintf(const UnicodeString &str) {
219 int32_t len = str.length();
220 int32_t bufLen = len + 16;
222 buf = new char[bufLen + 1];
223 actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
229 // Verify that a UErrorCode is successful; exit(1) if not
230 void check(UErrorCode& status, const char* msg) {
231 if (U_FAILURE(status)) {
232 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
239 class DateFmtCreateFunction : public UPerfFunction
247 DateFmtCreateFunction(int a, const char* loc)
253 virtual void call(UErrorCode* /* status */)
258 // (dates are imported from datedata.h)
259 for(int j = 0; j < num; j++) {
260 fmt = DateFormat::createDateTimeInstance(
261 DateFormat::kShort, DateFormat::kFull, loc);
266 virtual long getOperationsPerIteration()
273 class DateFmtCopyFunction : public UPerfFunction
281 DateFmtCopyFunction()
286 DateFmtCopyFunction(int a, const char* loc)
292 virtual void call(UErrorCode* /* status */)
295 UErrorCode status2 = U_ZERO_ERROR;
296 DateFormat *fmt = DateFormat::createDateTimeInstance(
297 DateFormat::kShort, DateFormat::kFull, loc);
298 for(int j = 0; j < num; j++) {
299 Format *cp = fmt->clone();
305 virtual long getOperationsPerIteration()
310 // Verify that a UErrorCode is successful; exit(1) if not
311 void check(UErrorCode& status, const char* msg) {
312 if (U_FAILURE(status)) {
313 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
320 class DIFCreateFunction : public UPerfFunction
333 DIFCreateFunction(int a, const char* loc)
339 virtual void call(UErrorCode* /* status */)
341 UErrorCode status2 = U_ZERO_ERROR;
345 cal = Calendar::createInstance(status2);
346 check(status2, "Calendar::createInstance");
347 zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
348 cal->adoptTimeZone(zone);
351 UnicodeString skeleton("yMMMMdHms");
353 for(int j = 0; j < num; j++) {
354 DateIntervalFormat* fmt(DateIntervalFormat::createInstance(skeleton, loc, status2));
360 virtual long getOperationsPerIteration()
365 // Verify that a UErrorCode is successful; exit(1) if not
366 void check(UErrorCode& status, const char* msg) {
367 if (U_FAILURE(status)) {
368 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
375 class TimeZoneCreateFunction : public UPerfFunction
383 TimeZoneCreateFunction()
388 TimeZoneCreateFunction(int a, const char* loc)
394 virtual void call(UErrorCode* /* status */)
397 UnicodeString tzname("UTC");
398 for(int j = 0; j < num; j++) {
399 TimeZone* tz(TimeZone::createTimeZone(tzname));
404 virtual long getOperationsPerIteration()
409 // Verify that a UErrorCode is successful; exit(1) if not
410 void check(UErrorCode& status, const char* msg) {
411 if (U_FAILURE(status)) {
412 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
419 class DTPatternGeneratorCreateFunction : public UPerfFunction
427 DTPatternGeneratorCreateFunction()
432 DTPatternGeneratorCreateFunction(int a, const char* loc)
438 virtual void call(UErrorCode* /* status */)
440 UErrorCode status2 = U_ZERO_ERROR;
443 for(int j = 0; j < num; j++) {
444 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
449 virtual long getOperationsPerIteration()
454 // Verify that a UErrorCode is successful; exit(1) if not
455 void check(UErrorCode& status, const char* msg) {
456 if (U_FAILURE(status)) {
457 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
464 class DTPatternGeneratorCopyFunction : public UPerfFunction
472 DTPatternGeneratorCopyFunction()
477 DTPatternGeneratorCopyFunction(int a, const char* loc)
483 virtual void call(UErrorCode* /* status */)
485 UErrorCode status2 = U_ZERO_ERROR;
487 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
489 for(int j = 0; j < num; j++) {
490 DateTimePatternGenerator *cl = gen->clone();
496 virtual long getOperationsPerIteration()
501 // Verify that a UErrorCode is successful; exit(1) if not
502 void check(UErrorCode& status, const char* msg) {
503 if (U_FAILURE(status)) {
504 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
511 class DTPatternGeneratorBestValueFunction : public UPerfFunction
519 DTPatternGeneratorBestValueFunction()
524 DTPatternGeneratorBestValueFunction(int a, const char* loc)
530 virtual void call(UErrorCode* /* status */)
532 UErrorCode status2 = U_ZERO_ERROR;
534 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
535 UnicodeString skeleton("yMMMMdHms");
537 for(int j = 0; j < num; j++) {
538 gen->getBestPattern(skeleton, status2);
540 check(status2, "getBestPattern");
544 virtual long getOperationsPerIteration()
549 // Verify that a UErrorCode is successful; exit(1) if not
550 void check(UErrorCode& status, const char* msg) {
551 if (U_FAILURE(status)) {
552 printf("ERROR: %s (%s)\n", u_errorName(status), msg);
559 class NumFmtFunction : public UPerfFunction
572 NumFmtFunction(int a, const char* loc)
578 virtual void call(UErrorCode* status2)
581 UErrorCode status = U_ZERO_ERROR;
583 // Create a number formatter for the locale
584 NumberFormat *fmt = NumberFormat::createInstance(loc, status);
586 // Parse a string. The string uses the digits '0' through '9'
587 // and the decimal separator '.', standard in the US locale
589 for(int i = 0; i < num; i++)
591 UnicodeString str("9876543210.123");
593 fmt->parse(str, result, status);
595 //uprintf(formattableToString(result));
598 // Take the number parsed above, and use the formatter to
600 str.remove(); // format() will APPEND to this string
601 fmt->format(result, str, status);
607 delete fmt; // Release the storage used by the formatter
614 U_LEFT_SQUARE_BRACKET=0x5b,
616 U_RIGHT_SQUARE_BRACKET=0x5d,
620 // Create a display string for a formattable
621 UnicodeString formattableToString(const Formattable& f) {
622 switch (f.getType()) {
623 case Formattable::kDate:
624 // TODO: Finish implementing this
625 return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD");
626 case Formattable::kDouble:
629 sprintf(buf, "%gD", f.getDouble());
630 return UnicodeString(buf, "");
632 case Formattable::kLong:
633 case Formattable::kInt64:
636 sprintf(buf, "%ldL", f.getLong());
637 return UnicodeString(buf, "");
639 case Formattable::kString:
640 return UnicodeString((UChar)U_DQUOTE).append(f.getString()).append((UChar)U_DQUOTE);
641 case Formattable::kArray:
644 const Formattable* array = f.getArray(count);
645 UnicodeString result((UChar)U_LEFT_SQUARE_BRACKET);
646 for (i=0; i<count; ++i) {
648 (result += (UChar)U_COMMA) += (UChar)U_SPACE;
650 result += formattableToString(array[i]);
652 result += (UChar)U_RIGHT_SQUARE_BRACKET;
656 return UNICODE_STRING_SIMPLE("INVALID_Formattable");
660 virtual long getOperationsPerIteration()
665 // Print the given string to stdout using the UTF-8 converter (for debugging purposes only)
666 void uprintf(const UnicodeString &str) {
667 char stackBuffer[100];
670 int32_t bufLen = str.extract(0, 0x7fffffff, stackBuffer, sizeof(stackBuffer), "UTF-8");
671 if(bufLen < sizeof(stackBuffer)) {
674 buf = new char[bufLen + 1];
675 bufLen = str.extract(0, 0x7fffffff, buf, bufLen + 1, "UTF-8");
678 if(buf != stackBuffer) {
686 #define NUM_STRING "9876543210.123"
687 #define NUM_NUM 9876543210.123
688 class StdioNumFmtFunction : public UPerfFunction
696 StdioNumFmtFunction()
701 StdioNumFmtFunction(int a, const char* loc)
707 virtual void call(UErrorCode* status2)
710 UErrorCode status = U_ZERO_ERROR;
712 // Parse a string. The string uses the digits '0' through '9'
713 // and the decimal separator '.', standard in the US locale
717 const char *str = NUM_STRING;
719 for(int i = 0; i < num; i++)
721 if(sscanf(str, "%lg", &result)!=1) {
722 cout << "Failed Stdio: failed to sscanf" << endl;
723 *status2 = U_PARSE_ERROR;
727 sprintf(outbuf, "%lg", result);
730 if(result!=NUM_NUM) {
731 cout << "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM << " got " << result << endl;
732 *status2 = U_PARSE_ERROR;
734 if(strcmp(str,NUM_STRING)) {
735 cout << "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING << " got " << str << endl;
736 *status2 = U_PARSE_ERROR;
740 virtual long getOperationsPerIteration()
747 class CollationFunction : public UPerfFunction
753 UnicodeString *collation_strings;
756 * Unescape the strings
759 uint32_t listSize = UPRV_LENGTHOF(collation_strings_escaped);
760 collation_strings = new UnicodeString[listSize];
761 for(uint32_t k=0;k<listSize;k++) {
762 collation_strings[k] = collation_strings_escaped[k].unescape();
764 UnicodeString shorty((UChar32)0x12345);
775 ~CollationFunction() {
776 delete [] collation_strings;
779 CollationFunction(int a, const char* loc)
786 virtual void call(UErrorCode* status2)
788 uint32_t listSize = UPRV_LENGTHOF(collation_strings_escaped);
789 UErrorCode status = U_ZERO_ERROR;
790 Collator *coll = Collator::createInstance(Locale(locale), status);
792 for(int k = 0; k < num; k++)
795 for(i=listSize-1; i>=1; i--) {
797 if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) {
798 //cout << "Success!" << endl;
806 virtual long getOperationsPerIteration()
812 class DateFormatPerfTest : public UPerfTest
818 DateFormatPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
819 ~DateFormatPerfTest();
820 virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par);
822 UPerfFunction* DateFmt250();
823 UPerfFunction* DateFmt10000();
824 UPerfFunction* DateFmt100000();
825 UPerfFunction* DateFmtCreate250();
826 UPerfFunction* DateFmtCreate10000();
827 UPerfFunction* DateFmtCopy250();
828 UPerfFunction* DateFmtCopy10000();
829 UPerfFunction* BreakItWord250();
830 UPerfFunction* BreakItWord10000();
831 UPerfFunction* BreakItChar250();
832 UPerfFunction* BreakItChar10000();
833 UPerfFunction* NumFmt10000();
834 UPerfFunction* NumFmt100000();
835 UPerfFunction* Collation10000();
836 UPerfFunction* Collation100000();
837 UPerfFunction* DIFCreate250();
838 UPerfFunction* DIFCreate10000();
839 UPerfFunction* TimeZoneCreate250();
840 UPerfFunction* TimeZoneCreate10000();
841 UPerfFunction* DTPatternGeneratorCreate250();
842 UPerfFunction* DTPatternGeneratorCreate10000();
843 UPerfFunction* DTPatternGeneratorCopy250();
844 UPerfFunction* DTPatternGeneratorCopy10000();
845 UPerfFunction* DTPatternGeneratorBestValue250();
846 UPerfFunction* DTPatternGeneratorBestValue10000();
849 #endif // DateFmtPerf