2 **********************************************************************
3 * Copyright (c) 2002-2016,International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 **********************************************************************
10 #define _DATEFMTPERF_H
13 #include "unicode/stringpiece.h"
14 #include "unicode/unistr.h"
15 #include "unicode/uperf.h"
17 #include "unicode/dtitvfmt.h"
18 #include "unicode/utypes.h"
19 #include "unicode/datefmt.h"
20 #include "unicode/calendar.h"
21 #include "unicode/uclean.h"
22 #include "unicode/brkiter.h"
23 #include "unicode/numfmt.h"
24 #include "unicode/coll.h"
28 #include "breakdata.h"
29 #include "collationdata.h"
39 // Stubs for Windows API functions when building on UNIXes.
41 #if U_PLATFORM_USES_ONLY_WIN32_API
46 inline int FoldStringW(DWORD dwMapFlags
, const UChar
* lpSrcStr
,int cchSrc
, UChar
* lpDestStr
,int cchDest
);
49 class BreakItFunction
: public UPerfFunction
57 BreakItFunction(){num
= -1;}
58 BreakItFunction(int a
, bool b
){num
= a
; wordIteration
= b
;}
60 virtual void call(UErrorCode
* status
)
62 BreakIterator
* boundary
;
66 for(int i
= 0; i
< num
; i
++)
68 boundary
= BreakIterator::createWordInstance("en", *status
);
69 boundary
->setText(str
);
71 int32_t start
= boundary
->first();
72 for (int32_t end
= boundary
->next();
73 end
!= BreakIterator::DONE
;
74 start
= end
, end
= boundary
->next())
76 printTextRange( *boundary
, start
, end
);
81 else // character iteration
83 for(int i
= 0; i
< num
; i
++)
85 boundary
= BreakIterator::createCharacterInstance(Locale::getUS(), *status
);
86 boundary
->setText(str
);
88 int32_t start
= boundary
->first();
89 for (int32_t end
= boundary
->next();
90 end
!= BreakIterator::DONE
;
91 start
= end
, end
= boundary
->next())
93 printTextRange( *boundary
, start
, end
);
101 virtual long getOperationsPerIteration()
103 if(wordIteration
) return 125*num
;
107 void printUnicodeString(const UnicodeString
&s
) {
109 s
.extract(0, s
.length(), charBuf
, sizeof(charBuf
)-1, 0);
110 charBuf
[sizeof(charBuf
)-1] = 0;
111 printf("%s", charBuf
);
115 void printTextRange( BreakIterator
& iterator
,
116 int32_t start
, int32_t end
)
118 CharacterIterator
*strIter
= iterator
.getText().clone();
121 //printUnicodeString(UnicodeString(s, start, end-start));
126 // Print the given string to stdout (for debugging purposes)
127 void uprintf(const UnicodeString
&str
) {
129 int32_t len
= str
.length();
130 int32_t bufLen
= len
+ 16;
132 buf
= new char[bufLen
+ 1];
133 actualLen
= str
.extract(0, len
, buf
/*, bufLen*/); // Default codepage conversion
141 class DateFmtFunction
: public UPerfFunction
154 DateFmtFunction(int a
, const char* loc
)
160 virtual void call(UErrorCode
* status
)
163 UErrorCode status2
= U_ZERO_ERROR
;
169 cal
= Calendar::createInstance(status2
);
170 check(status2
, "Calendar::createInstance");
171 zone
= TimeZone::createTimeZone("GMT"); // Create a GMT zone
172 cal
->adoptTimeZone(zone
);
176 fmt
= DateFormat::createDateTimeInstance(
177 DateFormat::kShort
, DateFormat::kFull
, loc
);
180 // (dates are imported from datedata.h)
181 for(int j
= 0; j
< num
; j
++)
182 for(int i
= 0; i
< NUM_DATES
; i
++)
185 cal
->set(years
[i
], months
[i
], days
[i
]);
186 date
= cal
->getTime(status2
);
187 check(status2
, "Calendar::getTime");
189 fmt
->setCalendar(*cal
);
193 fmt
->format(date
, str
, status2
);
196 // Display the formatted date string
207 virtual long getOperationsPerIteration()
209 return NUM_DATES
* num
;
212 // Print the given string to stdout (for debugging purposes)
213 void uprintf(const UnicodeString
&str
) {
215 int32_t len
= str
.length();
216 int32_t bufLen
= len
+ 16;
218 buf
= new char[bufLen
+ 1];
219 actualLen
= str
.extract(0, len
, buf
/*, bufLen*/); // Default codepage conversion
225 // Verify that a UErrorCode is successful; exit(1) if not
226 void check(UErrorCode
& status
, const char* msg
) {
227 if (U_FAILURE(status
)) {
228 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
235 class DateFmtCreateFunction
: public UPerfFunction
243 DateFmtCreateFunction(int a
, const char* loc
)
249 virtual void call(UErrorCode
* /* status */)
254 // (dates are imported from datedata.h)
255 for(int j
= 0; j
< num
; j
++) {
256 fmt
= DateFormat::createDateTimeInstance(
257 DateFormat::kShort
, DateFormat::kFull
, loc
);
262 virtual long getOperationsPerIteration()
269 class DateFmtCopyFunction
: public UPerfFunction
277 DateFmtCopyFunction()
282 DateFmtCopyFunction(int a
, const char* loc
)
288 virtual void call(UErrorCode
* /* status */)
291 UErrorCode status2
= U_ZERO_ERROR
;
292 DateFormat
*fmt
= DateFormat::createDateTimeInstance(
293 DateFormat::kShort
, DateFormat::kFull
, loc
);
294 for(int j
= 0; j
< num
; j
++) {
295 Format
*cp
= fmt
->clone();
301 virtual long getOperationsPerIteration()
306 // Verify that a UErrorCode is successful; exit(1) if not
307 void check(UErrorCode
& status
, const char* msg
) {
308 if (U_FAILURE(status
)) {
309 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
316 class DIFCreateFunction
: public UPerfFunction
329 DIFCreateFunction(int a
, const char* loc
)
335 virtual void call(UErrorCode
* /* status */)
337 UErrorCode status2
= U_ZERO_ERROR
;
341 cal
= Calendar::createInstance(status2
);
342 check(status2
, "Calendar::createInstance");
343 zone
= TimeZone::createTimeZone("GMT"); // Create a GMT zone
344 cal
->adoptTimeZone(zone
);
347 UnicodeString
skeleton("yMMMMdHms");
349 for(int j
= 0; j
< num
; j
++) {
350 DateIntervalFormat
* fmt(DateIntervalFormat::createInstance(skeleton
, loc
, status2
));
356 virtual long getOperationsPerIteration()
361 // Verify that a UErrorCode is successful; exit(1) if not
362 void check(UErrorCode
& status
, const char* msg
) {
363 if (U_FAILURE(status
)) {
364 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
371 class TimeZoneCreateFunction
: public UPerfFunction
379 TimeZoneCreateFunction()
384 TimeZoneCreateFunction(int a
, const char* loc
)
390 virtual void call(UErrorCode
* /* status */)
393 UnicodeString
tzname("UTC");
394 for(int j
= 0; j
< num
; j
++) {
395 TimeZone
* tz(TimeZone::createTimeZone(tzname
));
400 virtual long getOperationsPerIteration()
405 // Verify that a UErrorCode is successful; exit(1) if not
406 void check(UErrorCode
& status
, const char* msg
) {
407 if (U_FAILURE(status
)) {
408 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
415 class DTPatternGeneratorCreateFunction
: public UPerfFunction
423 DTPatternGeneratorCreateFunction()
428 DTPatternGeneratorCreateFunction(int a
, const char* loc
)
434 virtual void call(UErrorCode
* /* status */)
436 UErrorCode status2
= U_ZERO_ERROR
;
439 for(int j
= 0; j
< num
; j
++) {
440 DateTimePatternGenerator
* gen(DateTimePatternGenerator::createInstance(loc
, status2
));
445 virtual long getOperationsPerIteration()
450 // Verify that a UErrorCode is successful; exit(1) if not
451 void check(UErrorCode
& status
, const char* msg
) {
452 if (U_FAILURE(status
)) {
453 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
460 class DTPatternGeneratorCopyFunction
: public UPerfFunction
468 DTPatternGeneratorCopyFunction()
473 DTPatternGeneratorCopyFunction(int a
, const char* loc
)
479 virtual void call(UErrorCode
* /* status */)
481 UErrorCode status2
= U_ZERO_ERROR
;
483 DateTimePatternGenerator
* gen(DateTimePatternGenerator::createInstance(loc
, status2
));
485 for(int j
= 0; j
< num
; j
++) {
486 DateTimePatternGenerator
*cl
= gen
->clone();
492 virtual long getOperationsPerIteration()
497 // Verify that a UErrorCode is successful; exit(1) if not
498 void check(UErrorCode
& status
, const char* msg
) {
499 if (U_FAILURE(status
)) {
500 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
507 class DTPatternGeneratorBestValueFunction
: public UPerfFunction
515 DTPatternGeneratorBestValueFunction()
520 DTPatternGeneratorBestValueFunction(int a
, const char* loc
)
526 virtual void call(UErrorCode
* /* status */)
528 UErrorCode status2
= U_ZERO_ERROR
;
530 DateTimePatternGenerator
* gen(DateTimePatternGenerator::createInstance(loc
, status2
));
531 UnicodeString
skeleton("yMMMMdHms");
533 for(int j
= 0; j
< num
; j
++) {
534 gen
->getBestPattern(skeleton
, status2
);
536 check(status2
, "getBestPattern");
540 virtual long getOperationsPerIteration()
545 // Verify that a UErrorCode is successful; exit(1) if not
546 void check(UErrorCode
& status
, const char* msg
) {
547 if (U_FAILURE(status
)) {
548 printf("ERROR: %s (%s)\n", u_errorName(status
), msg
);
555 class NumFmtFunction
: public UPerfFunction
568 NumFmtFunction(int a
, const char* loc
)
574 virtual void call(UErrorCode
* status2
)
577 UErrorCode status
= U_ZERO_ERROR
;
579 // Create a number formatter for the locale
580 NumberFormat
*fmt
= NumberFormat::createInstance(loc
, status
);
582 // Parse a string. The string uses the digits '0' through '9'
583 // and the decimal separator '.', standard in the US locale
585 for(int i
= 0; i
< num
; i
++)
587 UnicodeString
str("9876543210.123");
589 fmt
->parse(str
, result
, status
);
591 //uprintf(formattableToString(result));
594 // Take the number parsed above, and use the formatter to
596 str
.remove(); // format() will APPEND to this string
597 fmt
->format(result
, str
, status
);
603 delete fmt
; // Release the storage used by the formatter
610 U_LEFT_SQUARE_BRACKET
=0x5b,
612 U_RIGHT_SQUARE_BRACKET
=0x5d,
616 // Create a display string for a formattable
617 UnicodeString
formattableToString(const Formattable
& f
) {
618 switch (f
.getType()) {
619 case Formattable::kDate
:
620 // TODO: Finish implementing this
621 return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD");
622 case Formattable::kDouble
:
625 sprintf(buf
, "%gD", f
.getDouble());
626 return UnicodeString(buf
, "");
628 case Formattable::kLong
:
629 case Formattable::kInt64
:
632 sprintf(buf
, "%ldL", f
.getLong());
633 return UnicodeString(buf
, "");
635 case Formattable::kString
:
636 return UnicodeString((UChar
)U_DQUOTE
).append(f
.getString()).append((UChar
)U_DQUOTE
);
637 case Formattable::kArray
:
640 const Formattable
* array
= f
.getArray(count
);
641 UnicodeString
result((UChar
)U_LEFT_SQUARE_BRACKET
);
642 for (i
=0; i
<count
; ++i
) {
644 (result
+= (UChar
)U_COMMA
) += (UChar
)U_SPACE
;
646 result
+= formattableToString(array
[i
]);
648 result
+= (UChar
)U_RIGHT_SQUARE_BRACKET
;
652 return UNICODE_STRING_SIMPLE("INVALID_Formattable");
656 virtual long getOperationsPerIteration()
661 // Print the given string to stdout using the UTF-8 converter (for debugging purposes only)
662 void uprintf(const UnicodeString
&str
) {
663 char stackBuffer
[100];
666 int32_t bufLen
= str
.extract(0, 0x7fffffff, stackBuffer
, sizeof(stackBuffer
), "UTF-8");
667 if(bufLen
< sizeof(stackBuffer
)) {
670 buf
= new char[bufLen
+ 1];
671 bufLen
= str
.extract(0, 0x7fffffff, buf
, bufLen
+ 1, "UTF-8");
674 if(buf
!= stackBuffer
) {
682 #define NUM_STRING "9876543210.123"
683 #define NUM_NUM 9876543210.123
684 class StdioNumFmtFunction
: public UPerfFunction
692 StdioNumFmtFunction()
697 StdioNumFmtFunction(int a
, const char* loc
)
703 virtual void call(UErrorCode
* status2
)
706 UErrorCode status
= U_ZERO_ERROR
;
708 // Parse a string. The string uses the digits '0' through '9'
709 // and the decimal separator '.', standard in the US locale
713 const char *str
= NUM_STRING
;
715 for(int i
= 0; i
< num
; i
++)
717 if(sscanf(str
, "%lg", &result
)!=1) {
718 cout
<< "Failed Stdio: failed to sscanf" << endl
;
719 *status2
= U_PARSE_ERROR
;
723 sprintf(outbuf
, "%lg", result
);
726 if(result
!=NUM_NUM
) {
727 cout
<< "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM
<< " got " << result
<< endl
;
728 *status2
= U_PARSE_ERROR
;
730 if(strcmp(str
,NUM_STRING
)) {
731 cout
<< "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING
<< " got " << str
<< endl
;
732 *status2
= U_PARSE_ERROR
;
736 virtual long getOperationsPerIteration()
743 class CollationFunction
: public UPerfFunction
749 UnicodeString
*collation_strings
;
752 * Unescape the strings
755 uint32_t listSize
= UPRV_LENGTHOF(collation_strings_escaped
);
756 collation_strings
= new UnicodeString
[listSize
];
757 for(uint32_t k
=0;k
<listSize
;k
++) {
758 collation_strings
[k
] = collation_strings_escaped
[k
].unescape();
760 UnicodeString
shorty((UChar32
)0x12345);
771 ~CollationFunction() {
772 delete [] collation_strings
;
775 CollationFunction(int a
, const char* loc
)
782 virtual void call(UErrorCode
* status2
)
784 uint32_t listSize
= UPRV_LENGTHOF(collation_strings_escaped
);
785 UErrorCode status
= U_ZERO_ERROR
;
786 Collator
*coll
= Collator::createInstance(Locale(locale
), status
);
788 for(int k
= 0; k
< num
; k
++)
791 for(i
=listSize
-1; i
>=1; i
--) {
793 if(coll
->compare(collation_strings
[j
], collation_strings
[j
+1]) == UCOL_LESS
) {
794 //cout << "Success!" << endl;
802 virtual long getOperationsPerIteration()
808 class DateFormatPerfTest
: public UPerfTest
814 DateFormatPerfTest(int32_t argc
, const char* argv
[], UErrorCode
& status
);
815 ~DateFormatPerfTest();
816 virtual UPerfFunction
* runIndexedTest(int32_t index
, UBool exec
,const char* &name
, char* par
);
818 UPerfFunction
* DateFmt250();
819 UPerfFunction
* DateFmt10000();
820 UPerfFunction
* DateFmt100000();
821 UPerfFunction
* DateFmtCreate250();
822 UPerfFunction
* DateFmtCreate10000();
823 UPerfFunction
* DateFmtCopy250();
824 UPerfFunction
* DateFmtCopy10000();
825 UPerfFunction
* BreakItWord250();
826 UPerfFunction
* BreakItWord10000();
827 UPerfFunction
* BreakItChar250();
828 UPerfFunction
* BreakItChar10000();
829 UPerfFunction
* NumFmt10000();
830 UPerfFunction
* NumFmt100000();
831 UPerfFunction
* Collation10000();
832 UPerfFunction
* Collation100000();
833 UPerfFunction
* DIFCreate250();
834 UPerfFunction
* DIFCreate10000();
835 UPerfFunction
* TimeZoneCreate250();
836 UPerfFunction
* TimeZoneCreate10000();
837 UPerfFunction
* DTPatternGeneratorCreate250();
838 UPerfFunction
* DTPatternGeneratorCreate10000();
839 UPerfFunction
* DTPatternGeneratorCopy250();
840 UPerfFunction
* DTPatternGeneratorCopy10000();
841 UPerfFunction
* DTPatternGeneratorBestValue250();
842 UPerfFunction
* DTPatternGeneratorBestValue10000();
845 #endif // DateFmtPerf