2 ***********************************************************************
3 * © 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