• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BreakItFunction()55 	BreakItFunction(){num = -1;}
BreakItFunction(int a,bool b)56 	BreakItFunction(int a, bool b){num = a; wordIteration = b;}
57 
call(UErrorCode * status)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 
getOperationsPerIteration()99 	virtual long getOperationsPerIteration()
100 	{
101 		if(wordIteration) return 125*num;
102 		else return 355*num;
103 	}
104 
printUnicodeString(const UnicodeString & s)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 
printTextRange(BreakIterator & iterator,int32_t start,int32_t end)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)
uprintf(const UnicodeString & str)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 
DateFmtFunction()147 	DateFmtFunction()
148 	{
149 		num = -1;
150 	}
151 
DateFmtFunction(int a,const char * loc)152 	DateFmtFunction(int a, const char* loc)
153 	{
154 		num = a;
155         strcpy(locale, loc);
156 	}
157 
call(UErrorCode * status)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 
getOperationsPerIteration()205 	virtual long getOperationsPerIteration()
206 	{
207 		return NUM_DATES * num;
208 	}
209 
210 	// Print the given string to stdout (for debugging purposes)
uprintf(const UnicodeString & str)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
check(UErrorCode & status,const char * msg)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 
NumFmtFunction()241 	NumFmtFunction()
242 	{
243 		num = -1;
244 	}
245 
NumFmtFunction(int a,const char * loc)246 	NumFmtFunction(int a, const char* loc)
247 	{
248 		num = a;
249         strcpy(locale, loc);
250 	}
251 
call(UErrorCode * status2)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
formattableToString(const Formattable & f)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 
getOperationsPerIteration()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)
uprintf(const UnicodeString & str)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 	 */
init()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 
CollationFunction()379 	CollationFunction()
380 	{
381 		num = -1;
382 
383 		init();
384 	}
385 
~CollationFunction()386 	~CollationFunction() {
387 		delete [] collation_strings;
388 	}
389 
CollationFunction(int a,const char * loc)390 	CollationFunction(int a, const char* loc)
391 	{
392 		num = a;
393         strcpy(locale, loc);
394 		init();
395 	}
396 
call(UErrorCode * status2)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 
getOperationsPerIteration()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