Imported Upstream version 58.1
[platform/upstream/icu.git] / source / test / perf / DateFmtPerf / DateFmtPerf.h
1 /*
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 ***********************************************************************
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