]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/perf/DateFmtPerf/DateFmtPerf.h
ICU-59117.0.1.tar.gz
[apple/icu.git] / icuSources / test / perf / DateFmtPerf / DateFmtPerf.h
1 /*
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 ***********************************************************************
11 */
12
13 #ifndef _DATEFMTPERF_H
14 #define _DATEFMTPERF_H
15
16 #include "cmemory.h"
17 #include "unicode/stringpiece.h"
18 #include "unicode/unistr.h"
19 #include "unicode/uperf.h"
20
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"
29 #include "util.h"
30
31 #include "datedata.h"
32 #include "breakdata.h"
33 #include "collationdata.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include <fstream>
39
40 #include <iostream>
41 using namespace std;
42
43 // Stubs for Windows API functions when building on UNIXes.
44 //
45 #if U_PLATFORM_USES_ONLY_WIN32_API
46 // do nothing
47 #else
48 #define _UNICODE
49 typedef int DWORD;
50 inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
51 #endif
52
53 class BreakItFunction : public UPerfFunction
54 {
55 private:
56 int num;
57 bool wordIteration;
58
59 public:
60
61 BreakItFunction(){num = -1;}
62 BreakItFunction(int a, bool b){num = a; wordIteration = b;}
63
64 virtual void call(UErrorCode * status)
65 {
66 BreakIterator* boundary;
67
68 if(wordIteration)
69 {
70 for(int i = 0; i < num; i++)
71 {
72 boundary = BreakIterator::createWordInstance("en", *status);
73 boundary->setText(str);
74
75 int32_t start = boundary->first();
76 for (int32_t end = boundary->next();
77 end != BreakIterator::DONE;
78 start = end, end = boundary->next())
79 {
80 printTextRange( *boundary, start, end );
81 }
82 }
83 }
84
85 else // character iteration
86 {
87 for(int i = 0; i < num; i++)
88 {
89 boundary = BreakIterator::createCharacterInstance(Locale::getUS(), *status);
90 boundary->setText(str);
91
92 int32_t start = boundary->first();
93 for (int32_t end = boundary->next();
94 end != BreakIterator::DONE;
95 start = end, end = boundary->next())
96 {
97 printTextRange( *boundary, start, end );
98 }
99 }
100 }
101
102
103 }
104
105 virtual long getOperationsPerIteration()
106 {
107 if(wordIteration) return 125*num;
108 else return 355*num;
109 }
110
111 void printUnicodeString(const UnicodeString &s) {
112 char charBuf[1000];
113 s.extract(0, s.length(), charBuf, sizeof(charBuf)-1, 0);
114 charBuf[sizeof(charBuf)-1] = 0;
115 printf("%s", charBuf);
116 }
117
118
119 void printTextRange( BreakIterator& iterator,
120 int32_t start, int32_t end )
121 {
122 CharacterIterator *strIter = iterator.getText().clone();
123 UnicodeString s;
124 strIter->getText(s);
125 //printUnicodeString(UnicodeString(s, start, end-start));
126 //puts("");
127 delete strIter;
128 }
129
130 // Print the given string to stdout (for debugging purposes)
131 void uprintf(const UnicodeString &str) {
132 char *buf = 0;
133 int32_t len = str.length();
134 int32_t bufLen = len + 16;
135 int32_t actualLen;
136 buf = new char[bufLen + 1];
137 actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
138 buf[actualLen] = 0;
139 printf("%s", buf);
140 delete[] buf;
141 }
142
143 };
144
145 class DateFmtFunction : public UPerfFunction
146 {
147
148 private:
149 int num;
150 char locale[25];
151 public:
152
153 DateFmtFunction()
154 {
155 num = -1;
156 }
157
158 DateFmtFunction(int a, const char* loc)
159 {
160 num = a;
161 strcpy(locale, loc);
162 }
163
164 virtual void call(UErrorCode* status)
165 {
166
167 UErrorCode status2 = U_ZERO_ERROR;
168 Calendar *cal;
169 TimeZone *zone;
170 UnicodeString str;
171 UDate date;
172
173 cal = Calendar::createInstance(status2);
174 check(status2, "Calendar::createInstance");
175 zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
176 cal->adoptTimeZone(zone);
177
178 Locale loc(locale);
179 DateFormat *fmt;
180 fmt = DateFormat::createDateTimeInstance(
181 DateFormat::kShort, DateFormat::kFull, loc);
182
183
184 // (dates are imported from datedata.h)
185 for(int j = 0; j < num; j++)
186 for(int i = 0; i < NUM_DATES; i++)
187 {
188 cal->clear();
189 cal->set(years[i], months[i], days[i]);
190 date = cal->getTime(status2);
191 check(status2, "Calendar::getTime");
192
193 fmt->setCalendar(*cal);
194
195 // Format the date
196 str.remove();
197 fmt->format(date, str, status2);
198
199
200 // Display the formatted date string
201 //uprintf(str);
202 //printf("\n");
203
204 }
205
206 delete fmt;
207 delete cal;
208 //u_cleanup();
209 }
210
211 virtual long getOperationsPerIteration()
212 {
213 return NUM_DATES * num;
214 }
215
216 // Print the given string to stdout (for debugging purposes)
217 void uprintf(const UnicodeString &str) {
218 char *buf = 0;
219 int32_t len = str.length();
220 int32_t bufLen = len + 16;
221 int32_t actualLen;
222 buf = new char[bufLen + 1];
223 actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
224 buf[actualLen] = 0;
225 printf("%s", buf);
226 delete[] buf;
227 }
228
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);
233 exit(1);
234 }
235 }
236
237 };
238
239 class DateFmtCreateFunction : public UPerfFunction
240 {
241
242 private:
243 int num;
244 char locale[25];
245 public:
246
247 DateFmtCreateFunction(int a, const char* loc)
248 {
249 num = a;
250 strcpy(locale, loc);
251 }
252
253 virtual void call(UErrorCode* /* status */)
254 {
255
256 Locale loc(locale);
257 DateFormat *fmt;
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);
262 delete fmt;
263 }
264 }
265
266 virtual long getOperationsPerIteration()
267 {
268 return num;
269 }
270
271 };
272
273 class DateFmtCopyFunction : public UPerfFunction
274 {
275
276 private:
277 int num;
278 char locale[25];
279 public:
280
281 DateFmtCopyFunction()
282 {
283 num = -1;
284 }
285
286 DateFmtCopyFunction(int a, const char* loc)
287 {
288 num = a;
289 strcpy(locale, loc);
290 }
291
292 virtual void call(UErrorCode* /* status */)
293 {
294 Locale loc(locale);
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();
300 delete cp;
301 }
302 delete fmt;
303 }
304
305 virtual long getOperationsPerIteration()
306 {
307 return num;
308 }
309
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);
314 exit(1);
315 }
316 }
317
318 };
319
320 class DIFCreateFunction : public UPerfFunction
321 {
322
323 private:
324 int num;
325 char locale[25];
326 public:
327
328 DIFCreateFunction()
329 {
330 num = -1;
331 }
332
333 DIFCreateFunction(int a, const char* loc)
334 {
335 num = a;
336 strcpy(locale, loc);
337 }
338
339 virtual void call(UErrorCode* /* status */)
340 {
341 UErrorCode status2 = U_ZERO_ERROR;
342 Calendar *cal;
343 TimeZone *zone;
344
345 cal = Calendar::createInstance(status2);
346 check(status2, "Calendar::createInstance");
347 zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
348 cal->adoptTimeZone(zone);
349
350 Locale loc(locale);
351 UnicodeString skeleton("yMMMMdHms");
352
353 for(int j = 0; j < num; j++) {
354 DateIntervalFormat* fmt(DateIntervalFormat::createInstance(skeleton, loc, status2));
355 delete fmt;
356 }
357 delete cal;
358 }
359
360 virtual long getOperationsPerIteration()
361 {
362 return num;
363 }
364
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);
369 exit(1);
370 }
371 }
372
373 };
374
375 class TimeZoneCreateFunction : public UPerfFunction
376 {
377
378 private:
379 int num;
380 char locale[25];
381 public:
382
383 TimeZoneCreateFunction()
384 {
385 num = -1;
386 }
387
388 TimeZoneCreateFunction(int a, const char* loc)
389 {
390 num = a;
391 strcpy(locale, loc);
392 }
393
394 virtual void call(UErrorCode* /* status */)
395 {
396 Locale loc(locale);
397 UnicodeString tzname("UTC");
398 for(int j = 0; j < num; j++) {
399 TimeZone* tz(TimeZone::createTimeZone(tzname));
400 delete tz;
401 }
402 }
403
404 virtual long getOperationsPerIteration()
405 {
406 return num;
407 }
408
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);
413 exit(1);
414 }
415 }
416
417 };
418
419 class DTPatternGeneratorCreateFunction : public UPerfFunction
420 {
421
422 private:
423 int num;
424 char locale[25];
425 public:
426
427 DTPatternGeneratorCreateFunction()
428 {
429 num = -1;
430 }
431
432 DTPatternGeneratorCreateFunction(int a, const char* loc)
433 {
434 num = a;
435 strcpy(locale, loc);
436 }
437
438 virtual void call(UErrorCode* /* status */)
439 {
440 UErrorCode status2 = U_ZERO_ERROR;
441 Locale loc(locale);
442
443 for(int j = 0; j < num; j++) {
444 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
445 delete gen;
446 }
447 }
448
449 virtual long getOperationsPerIteration()
450 {
451 return num;
452 }
453
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);
458 exit(1);
459 }
460 }
461
462 };
463
464 class DTPatternGeneratorCopyFunction : public UPerfFunction
465 {
466
467 private:
468 int num;
469 char locale[25];
470 public:
471
472 DTPatternGeneratorCopyFunction()
473 {
474 num = -1;
475 }
476
477 DTPatternGeneratorCopyFunction(int a, const char* loc)
478 {
479 num = a;
480 strcpy(locale, loc);
481 }
482
483 virtual void call(UErrorCode* /* status */)
484 {
485 UErrorCode status2 = U_ZERO_ERROR;
486 Locale loc(locale);
487 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
488
489 for(int j = 0; j < num; j++) {
490 DateTimePatternGenerator *cl = gen->clone();
491 delete cl;
492 }
493 delete gen;
494 }
495
496 virtual long getOperationsPerIteration()
497 {
498 return num;
499 }
500
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);
505 exit(1);
506 }
507 }
508
509 };
510
511 class DTPatternGeneratorBestValueFunction : public UPerfFunction
512 {
513
514 private:
515 int num;
516 char locale[25];
517 public:
518
519 DTPatternGeneratorBestValueFunction()
520 {
521 num = -1;
522 }
523
524 DTPatternGeneratorBestValueFunction(int a, const char* loc)
525 {
526 num = a;
527 strcpy(locale, loc);
528 }
529
530 virtual void call(UErrorCode* /* status */)
531 {
532 UErrorCode status2 = U_ZERO_ERROR;
533 Locale loc(locale);
534 DateTimePatternGenerator* gen(DateTimePatternGenerator::createInstance(loc, status2));
535 UnicodeString skeleton("yMMMMdHms");
536
537 for(int j = 0; j < num; j++) {
538 gen->getBestPattern(skeleton, status2);
539 }
540 check(status2, "getBestPattern");
541 delete gen;
542 }
543
544 virtual long getOperationsPerIteration()
545 {
546 return num;
547 }
548
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);
553 exit(1);
554 }
555 }
556
557 };
558
559 class NumFmtFunction : public UPerfFunction
560 {
561
562 private:
563 int num;
564 char locale[25];
565 public:
566
567 NumFmtFunction()
568 {
569 num = -1;
570 }
571
572 NumFmtFunction(int a, const char* loc)
573 {
574 num = a;
575 strcpy(locale, loc);
576 }
577
578 virtual void call(UErrorCode* status2)
579 {
580 Locale loc(locale);
581 UErrorCode status = U_ZERO_ERROR;
582
583 // Create a number formatter for the locale
584 NumberFormat *fmt = NumberFormat::createInstance(loc, status);
585
586 // Parse a string. The string uses the digits '0' through '9'
587 // and the decimal separator '.', standard in the US locale
588
589 for(int i = 0; i < num; i++)
590 {
591 UnicodeString str("9876543210.123");
592 Formattable result;
593 fmt->parse(str, result, status);
594
595 //uprintf(formattableToString(result));
596 //printf("\n");
597
598 // Take the number parsed above, and use the formatter to
599 // format it.
600 str.remove(); // format() will APPEND to this string
601 fmt->format(result, str, status);
602
603 //uprintf(str);
604 //printf("\n");
605 }
606
607 delete fmt; // Release the storage used by the formatter
608 }
609
610 enum {
611 U_SPACE=0x20,
612 U_DQUOTE=0x22,
613 U_COMMA=0x2c,
614 U_LEFT_SQUARE_BRACKET=0x5b,
615 U_BACKSLASH=0x5c,
616 U_RIGHT_SQUARE_BRACKET=0x5d,
617 U_SMALL_U=0x75
618 };
619
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:
627 {
628 char buf[256];
629 sprintf(buf, "%gD", f.getDouble());
630 return UnicodeString(buf, "");
631 }
632 case Formattable::kLong:
633 case Formattable::kInt64:
634 {
635 char buf[256];
636 sprintf(buf, "%ldL", f.getLong());
637 return UnicodeString(buf, "");
638 }
639 case Formattable::kString:
640 return UnicodeString((UChar)U_DQUOTE).append(f.getString()).append((UChar)U_DQUOTE);
641 case Formattable::kArray:
642 {
643 int32_t i, count;
644 const Formattable* array = f.getArray(count);
645 UnicodeString result((UChar)U_LEFT_SQUARE_BRACKET);
646 for (i=0; i<count; ++i) {
647 if (i > 0) {
648 (result += (UChar)U_COMMA) += (UChar)U_SPACE;
649 }
650 result += formattableToString(array[i]);
651 }
652 result += (UChar)U_RIGHT_SQUARE_BRACKET;
653 return result;
654 }
655 default:
656 return UNICODE_STRING_SIMPLE("INVALID_Formattable");
657 }
658 }
659
660 virtual long getOperationsPerIteration()
661 {
662 return num;
663 }
664
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];
668 char *buf = 0;
669
670 int32_t bufLen = str.extract(0, 0x7fffffff, stackBuffer, sizeof(stackBuffer), "UTF-8");
671 if(bufLen < sizeof(stackBuffer)) {
672 buf = stackBuffer;
673 } else {
674 buf = new char[bufLen + 1];
675 bufLen = str.extract(0, 0x7fffffff, buf, bufLen + 1, "UTF-8");
676 }
677 printf("%s", buf);
678 if(buf != stackBuffer) {
679 delete[] buf;
680 }
681 }
682 };
683
684
685
686 #define NUM_STRING "9876543210.123"
687 #define NUM_NUM 9876543210.123
688 class StdioNumFmtFunction : public UPerfFunction
689 {
690
691 private:
692 int num;
693 char locale[25];
694 public:
695
696 StdioNumFmtFunction()
697 {
698 num = -1;
699 }
700
701 StdioNumFmtFunction(int a, const char* loc)
702 {
703 num = a;
704 strcpy(locale, loc);
705 }
706
707 virtual void call(UErrorCode* status2)
708 {
709 Locale loc(locale);
710 UErrorCode status = U_ZERO_ERROR;
711
712 // Parse a string. The string uses the digits '0' through '9'
713 // and the decimal separator '.', standard in the US locale
714
715 double result;
716 char outbuf[500];
717 const char *str = NUM_STRING;
718
719 for(int i = 0; i < num; i++)
720 {
721 if(sscanf(str, "%lg", &result)!=1) {
722 cout << "Failed Stdio: failed to sscanf" << endl;
723 *status2 = U_PARSE_ERROR;
724 return;
725 }
726
727 sprintf(outbuf, "%lg", result);
728 }
729
730 if(result!=NUM_NUM) {
731 cout << "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM << " got " << result << endl;
732 *status2 = U_PARSE_ERROR;
733 }
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;
737 }
738 }
739
740 virtual long getOperationsPerIteration()
741 {
742 return num;
743 }
744
745 };
746
747 class CollationFunction : public UPerfFunction
748 {
749
750 private:
751 int num;
752 char locale[25];
753 UnicodeString *collation_strings;
754
755 /**
756 * Unescape the strings
757 */
758 void init() {
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();
763 }
764 UnicodeString shorty((UChar32)0x12345);
765 }
766 public:
767
768 CollationFunction()
769 {
770 num = -1;
771
772 init();
773 }
774
775 ~CollationFunction() {
776 delete [] collation_strings;
777 }
778
779 CollationFunction(int a, const char* loc)
780 {
781 num = a;
782 strcpy(locale, loc);
783 init();
784 }
785
786 virtual void call(UErrorCode* status2)
787 {
788 uint32_t listSize = UPRV_LENGTHOF(collation_strings_escaped);
789 UErrorCode status = U_ZERO_ERROR;
790 Collator *coll = Collator::createInstance(Locale(locale), status);
791
792 for(int k = 0; k < num; k++)
793 {
794 uint32_t i, j;
795 for(i=listSize-1; i>=1; i--) {
796 for(j=0; j<i; j++) {
797 if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) {
798 //cout << "Success!" << endl;
799 }
800 }
801 }
802 }
803 delete coll;
804 }
805
806 virtual long getOperationsPerIteration()
807 {
808 return num;
809 }
810 };
811
812 class DateFormatPerfTest : public UPerfTest
813 {
814 private:
815
816 public:
817
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);
821
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();
847 };
848
849 #endif // DateFmtPerf