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