Home | History | Annotate | Download | only in DateFmtPerf
      1 /*
      2 **********************************************************************
      3 * Copyright (c) 2002-2010,International Business Machines
      4 * Corporation and others.  All Rights Reserved.
      5 **********************************************************************
      6 **********************************************************************
      7 */
      8 
      9 #ifndef _DATEFMTPERF_H
     10 #define _DATEFMTPERF_H
     11 
     12 
     13 #include "unicode/stringpiece.h"
     14 #include "unicode/unistr.h"
     15 #include "unicode/uperf.h"
     16 
     17 #include "unicode/utypes.h"
     18 #include "unicode/datefmt.h"
     19 #include "unicode/calendar.h"
     20 #include "unicode/uclean.h"
     21 #include "unicode/brkiter.h"
     22 #include "unicode/numfmt.h"
     23 #include "unicode/coll.h"
     24 #include "util.h"
     25 
     26 #include "datedata.h"
     27 #include "breakdata.h"
     28 #include "collationdata.h"
     29 
     30 #include <stdlib.h>
     31 #include <fstream>
     32 #include <string>
     33 
     34 #include <iostream>
     35 using namespace std;
     36 
     37 //  Stubs for Windows API functions when building on UNIXes.
     38 //
     39 #if defined(U_WINDOWS)
     40 // do nothing
     41 #else
     42 #define _UNICODE
     43 typedef int DWORD;
     44 inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
     45 #endif
     46 
     47 class BreakItFunction : public UPerfFunction
     48 {
     49 private:
     50 	int num;
     51 	bool wordIteration;
     52 
     53 public:
     54 
     55 	BreakItFunction(){num = -1;}
     56 	BreakItFunction(int a, bool b){num = a; wordIteration = b;}
     57 
     58 	virtual void call(UErrorCode *status)
     59 	{
     60 		BreakIterator* boundary;
     61 
     62 		if(wordIteration)
     63 		{
     64 			for(int i = 0; i < num; i++)
     65 			{
     66 				boundary = BreakIterator::createWordInstance("en", *status);
     67 				boundary->setText(str);
     68 
     69 				int32_t start = boundary->first();
     70 				for (int32_t end = boundary->next();
     71 					 end != BreakIterator::DONE;
     72 					 start = end, end = boundary->next())
     73 				{
     74 					printTextRange( *boundary, start, end );
     75 				}
     76 			}
     77 		}
     78 
     79 		else // character iteration
     80 		{
     81 			for(int i = 0; i < num; i++)
     82             {
     83 				boundary = BreakIterator::createCharacterInstance(Locale::getUS(), *status);
     84 				boundary->setText(str);
     85 
     86 				int32_t start = boundary->first();
     87 				for (int32_t end = boundary->next();
     88 					 end != BreakIterator::DONE;
     89 					 start = end, end = boundary->next())
     90 				{
     91 					printTextRange( *boundary, start, end );
     92 				}
     93 			}
     94 		}
     95 
     96 
     97 	}
     98 
     99 	virtual long getOperationsPerIteration()
    100 	{
    101 		if(wordIteration) return 125*num;
    102 		else return 355*num;
    103 	}
    104 
    105 	void printUnicodeString(const UnicodeString &s) {
    106 		char charBuf[1000];
    107 		s.extract(0, s.length(), charBuf, sizeof(charBuf)-1, 0);
    108 		charBuf[sizeof(charBuf)-1] = 0;
    109 		printf("%s", charBuf);
    110 	}
    111 
    112 
    113 	void printTextRange( BreakIterator& iterator,
    114 						int32_t start, int32_t end )
    115 	{
    116 		CharacterIterator *strIter = iterator.getText().clone();
    117 		UnicodeString  s;
    118 		strIter->getText(s);
    119 		//printUnicodeString(UnicodeString(s, start, end-start));
    120 		//puts("");
    121 		delete strIter;
    122 	}
    123 
    124 	// Print the given string to stdout (for debugging purposes)
    125 	void uprintf(const UnicodeString &str) {
    126 		char *buf = 0;
    127 		int32_t len = str.length();
    128 		int32_t bufLen = len + 16;
    129 		int32_t actualLen;
    130 		buf = new char[bufLen + 1];
    131 		actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
    132 		buf[actualLen] = 0;
    133 		printf("%s", buf);
    134 		delete[] buf;
    135 	}
    136 
    137 };
    138 
    139 class DateFmtFunction : public UPerfFunction
    140 {
    141 
    142 private:
    143 	int num;
    144     char locale[25];
    145 public:
    146 
    147 	DateFmtFunction()
    148 	{
    149 		num = -1;
    150 	}
    151 
    152 	DateFmtFunction(int a, const char* loc)
    153 	{
    154 		num = a;
    155         strcpy(locale, loc);
    156 	}
    157 
    158 	virtual void call(UErrorCode* status)
    159 	{
    160 
    161 		UErrorCode status2 = U_ZERO_ERROR;
    162 		Calendar *cal;
    163 		TimeZone *zone;
    164 		UnicodeString str;
    165 		UDate date;
    166 
    167 		cal = Calendar::createInstance(status2);
    168 		check(status2, "Calendar::createInstance");
    169 		zone = TimeZone::createTimeZone("GMT"); // Create a GMT zone
    170 		cal->adoptTimeZone(zone);
    171 
    172 		Locale loc(locale);
    173 		DateFormat *fmt;
    174 		fmt = DateFormat::createDateTimeInstance(
    175 								DateFormat::kShort, DateFormat::kFull, loc);
    176 
    177 
    178 		// (dates are imported from datedata.h)
    179 		for(int j = 0; j < num; j++)
    180 			for(int i = 0; i < NUM_DATES; i++)
    181 			{
    182 				cal->clear();
    183 				cal->set(years[i], months[i], days[i]);
    184 				date = cal->getTime(status2);
    185 				check(status2, "Calendar::getTime");
    186 
    187 				fmt->setCalendar(*cal);
    188 
    189 				// Format the date
    190 				str.remove();
    191 				fmt->format(date, str, status2);
    192 
    193 
    194 				// Display the formatted date string
    195 				//uprintf(str);
    196 				//printf("\n");
    197 
    198 			}
    199 
    200 		delete fmt;
    201 		delete cal;
    202 		//u_cleanup();
    203 	}
    204 
    205 	virtual long getOperationsPerIteration()
    206 	{
    207 		return NUM_DATES * num;
    208 	}
    209 
    210 	// Print the given string to stdout (for debugging purposes)
    211 	void uprintf(const UnicodeString &str) {
    212 		char *buf = 0;
    213 		int32_t len = str.length();
    214 		int32_t bufLen = len + 16;
    215 		int32_t actualLen;
    216 		buf = new char[bufLen + 1];
    217 		actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
    218 		buf[actualLen] = 0;
    219 		printf("%s", buf);
    220 		delete[] buf;
    221 	}
    222 
    223 	// Verify that a UErrorCode is successful; exit(1) if not
    224 	void check(UErrorCode& status, const char* msg) {
    225 		if (U_FAILURE(status)) {
    226 			printf("ERROR: %s (%s)\n", u_errorName(status), msg);
    227 			exit(1);
    228 		}
    229 	}
    230 
    231 };
    232 
    233 class NumFmtFunction : public UPerfFunction
    234 {
    235 
    236 private:
    237 	int num;
    238     char locale[25];
    239 public:
    240 
    241 	NumFmtFunction()
    242 	{
    243 		num = -1;
    244 	}
    245 
    246 	NumFmtFunction(int a, const char* loc)
    247 	{
    248 		num = a;
    249         strcpy(locale, loc);
    250 	}
    251 
    252 	virtual void call(UErrorCode* status2)
    253 	{
    254         Locale loc(locale);
    255         UErrorCode status = U_ZERO_ERROR;
    256 
    257         // Create a number formatter for the locale
    258         NumberFormat *fmt = NumberFormat::createInstance(loc, status);
    259 
    260         // Parse a string.  The string uses the digits '0' through '9'
    261         // and the decimal separator '.', standard in the US locale
    262 
    263         for(int i = 0; i < num; i++)
    264         {
    265             UnicodeString str("9876543210.123");
    266             Formattable result;
    267             fmt->parse(str, result, status);
    268 
    269             //uprintf(formattableToString(result));
    270             //printf("\n");
    271 
    272             // Take the number parsed above, and use the formatter to
    273             // format it.
    274             str.remove(); // format() will APPEND to this string
    275             fmt->format(result, str, status);
    276 
    277             //uprintf(str);
    278             //printf("\n");
    279         }
    280 
    281         delete fmt; // Release the storage used by the formatter
    282     }
    283 
    284     enum {
    285         U_SPACE=0x20,
    286         U_DQUOTE=0x22,
    287         U_COMMA=0x2c,
    288         U_LEFT_SQUARE_BRACKET=0x5b,
    289         U_BACKSLASH=0x5c,
    290         U_RIGHT_SQUARE_BRACKET=0x5d,
    291         U_SMALL_U=0x75
    292     };
    293 
    294     // Create a display string for a formattable
    295     UnicodeString formattableToString(const Formattable& f) {
    296         switch (f.getType()) {
    297         case Formattable::kDate:
    298             // TODO: Finish implementing this
    299             return UNICODE_STRING_SIMPLE("Formattable_DATE_TBD");
    300         case Formattable::kDouble:
    301             {
    302                 char buf[256];
    303                 sprintf(buf, "%gD", f.getDouble());
    304                 return UnicodeString(buf, "");
    305             }
    306         case Formattable::kLong:
    307         case Formattable::kInt64:
    308             {
    309                 char buf[256];
    310                 sprintf(buf, "%ldL", f.getLong());
    311                 return UnicodeString(buf, "");
    312             }
    313         case Formattable::kString:
    314             return UnicodeString((UChar)U_DQUOTE).append(f.getString()).append((UChar)U_DQUOTE);
    315         case Formattable::kArray:
    316             {
    317                 int32_t i, count;
    318                 const Formattable* array = f.getArray(count);
    319                 UnicodeString result((UChar)U_LEFT_SQUARE_BRACKET);
    320                 for (i=0; i<count; ++i) {
    321                     if (i > 0) {
    322                         (result += (UChar)U_COMMA) += (UChar)U_SPACE;
    323                     }
    324                     result += formattableToString(array[i]);
    325                 }
    326                 result += (UChar)U_RIGHT_SQUARE_BRACKET;
    327                 return result;
    328             }
    329         default:
    330             return UNICODE_STRING_SIMPLE("INVALID_Formattable");
    331         }
    332     }
    333 
    334 	virtual long getOperationsPerIteration()
    335 	{
    336 		return num;
    337 	}
    338 
    339     // Print the given string to stdout using the UTF-8 converter (for debugging purposes only)
    340     void uprintf(const UnicodeString &str) {
    341         char stackBuffer[100];
    342         char *buf = 0;
    343 
    344         int32_t bufLen = str.extract(0, 0x7fffffff, stackBuffer, sizeof(stackBuffer), "UTF-8");
    345         if(bufLen < sizeof(stackBuffer)) {
    346             buf = stackBuffer;
    347         } else {
    348             buf = new char[bufLen + 1];
    349             bufLen = str.extract(0, 0x7fffffff, buf, bufLen + 1, "UTF-8");
    350         }
    351         printf("%s", buf);
    352         if(buf != stackBuffer) {
    353             delete[] buf;
    354         }
    355     }
    356 };
    357 
    358 class CollationFunction : public UPerfFunction
    359 {
    360 
    361 private:
    362 	int num;
    363     char locale[25];
    364 	UnicodeString *collation_strings;
    365 
    366 	/**
    367 	 * Unescape the strings
    368 	 */
    369 	void init() {
    370         uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]);
    371 		collation_strings = new UnicodeString[listSize];
    372 		for(uint32_t k=0;k<listSize;k++) {
    373 			collation_strings[k] = collation_strings_escaped[k].unescape();
    374 		}
    375 		UnicodeString shorty((UChar32)0x12345);
    376 	}
    377 public:
    378 
    379 	CollationFunction()
    380 	{
    381 		num = -1;
    382 
    383 		init();
    384 	}
    385 
    386 	~CollationFunction() {
    387 		delete [] collation_strings;
    388 	}
    389 
    390 	CollationFunction(int a, const char* loc)
    391 	{
    392 		num = a;
    393         strcpy(locale, loc);
    394 		init();
    395 	}
    396 
    397 	virtual void call(UErrorCode* status2)
    398 	{
    399         uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]);
    400         UErrorCode status = U_ZERO_ERROR;
    401         Collator *coll = Collator::createInstance(Locale(locale), status);
    402 
    403         for(int k = 0; k < num; k++)
    404         {
    405             uint32_t i, j;
    406             for(i=listSize-1; i>=1; i--) {
    407                 for(j=0; j<i; j++) {
    408                     if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) {
    409                     //cout << "Success!" << endl;
    410                      }
    411                 }
    412             }
    413          }
    414         delete coll;
    415     }
    416 
    417 	virtual long getOperationsPerIteration()
    418 	{
    419 		return num;
    420 	}
    421 };
    422 
    423 class DateFormatPerfTest : public UPerfTest
    424 {
    425 private:
    426 
    427 public:
    428 
    429 	DateFormatPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
    430 	~DateFormatPerfTest();
    431 	virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par);
    432 
    433 	UPerfFunction* DateFmt250();
    434 	UPerfFunction* DateFmt10000();
    435 	UPerfFunction* DateFmt100000();
    436 	UPerfFunction* BreakItWord250();
    437 	UPerfFunction* BreakItWord10000();
    438 	UPerfFunction* BreakItChar250();
    439 	UPerfFunction* BreakItChar10000();
    440     UPerfFunction* NumFmt10000();
    441     UPerfFunction* NumFmt100000();
    442     UPerfFunction* Collation10000();
    443     UPerfFunction* Collation100000();
    444 };
    445 
    446 #endif // DateFmtPerf
    447