• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 U_PLATFORM_USES_ONLY_WIN32_API
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 
BreakItFunction()56 	BreakItFunction(){num = -1;}
BreakItFunction(int a,bool b)57 	BreakItFunction(int a, bool b){num = a; wordIteration = b;}
58 
call(UErrorCode * status)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 
getOperationsPerIteration()100 	virtual long getOperationsPerIteration()
101 	{
102 		if(wordIteration) return 125*num;
103 		else return 355*num;
104 	}
105 
printUnicodeString(const UnicodeString & s)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 
printTextRange(BreakIterator & iterator,int32_t start,int32_t end)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)
uprintf(const UnicodeString & str)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 
DateFmtFunction()148 	DateFmtFunction()
149 	{
150 		num = -1;
151 	}
152 
DateFmtFunction(int a,const char * loc)153 	DateFmtFunction(int a, const char* loc)
154 	{
155 		num = a;
156         strcpy(locale, loc);
157 	}
158 
call(UErrorCode * status)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 
getOperationsPerIteration()206 	virtual long getOperationsPerIteration()
207 	{
208 		return NUM_DATES * num;
209 	}
210 
211 	// Print the given string to stdout (for debugging purposes)
uprintf(const UnicodeString & str)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
check(UErrorCode & status,const char * msg)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 
NumFmtFunction()242 	NumFmtFunction()
243 	{
244 		num = -1;
245 	}
246 
NumFmtFunction(int a,const char * loc)247 	NumFmtFunction(int a, const char* loc)
248 	{
249 		num = a;
250         strcpy(locale, loc);
251 	}
252 
call(UErrorCode * status2)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
formattableToString(const Formattable & f)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 
getOperationsPerIteration()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)
uprintf(const UnicodeString & str)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 
360 
361 #define NUM_STRING "9876543210.123"
362 #define NUM_NUM 9876543210.123
363 class StdioNumFmtFunction : public UPerfFunction
364 {
365 
366  private:
367   int num;
368   char locale[25];
369  public:
370 
StdioNumFmtFunction()371   StdioNumFmtFunction()
372     {
373       num = -1;
374     }
375 
StdioNumFmtFunction(int a,const char * loc)376   StdioNumFmtFunction(int a, const char* loc)
377     {
378       num = a;
379       strcpy(locale, loc);
380     }
381 
call(UErrorCode * status2)382   virtual void call(UErrorCode* status2)
383   {
384     Locale loc(locale);
385     UErrorCode status = U_ZERO_ERROR;
386 
387     // Parse a string.  The string uses the digits '0' through '9'
388     // and the decimal separator '.', standard in the US locale
389 
390     double result;
391     char outbuf[500];
392     const char *str = NUM_STRING;
393 
394     for(int i = 0; i < num; i++)
395       {
396         if(sscanf(str, "%lg", &result)!=1) {
397           cout << "Failed Stdio: failed to sscanf" << endl;
398           *status2 = U_PARSE_ERROR;
399           return;
400         }
401 
402         sprintf(outbuf, "%lg", result);
403       }
404 
405     if(result!=NUM_NUM) {
406       cout << "Failed Stdio: sscanf got wrong result, expected " << NUM_NUM << " got " << result << endl;
407       *status2 = U_PARSE_ERROR;
408     }
409     if(strcmp(str,NUM_STRING)) {
410       cout << "Failed Stdio: sprintf got wrong result, expected " << NUM_STRING << " got " << str << endl;
411       *status2 = U_PARSE_ERROR;
412     }
413   }
414 
getOperationsPerIteration()415   virtual long getOperationsPerIteration()
416   {
417     return num;
418   }
419 
420 };
421 
422 class CollationFunction : public UPerfFunction
423 {
424 
425 private:
426 	int num;
427     char locale[25];
428 	UnicodeString *collation_strings;
429 
430 	/**
431 	 * Unescape the strings
432 	 */
init()433 	void init() {
434         uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]);
435 		collation_strings = new UnicodeString[listSize];
436 		for(uint32_t k=0;k<listSize;k++) {
437 			collation_strings[k] = collation_strings_escaped[k].unescape();
438 		}
439 		UnicodeString shorty((UChar32)0x12345);
440 	}
441 public:
442 
CollationFunction()443 	CollationFunction()
444 	{
445 		num = -1;
446 
447 		init();
448 	}
449 
~CollationFunction()450 	~CollationFunction() {
451 		delete [] collation_strings;
452 	}
453 
CollationFunction(int a,const char * loc)454 	CollationFunction(int a, const char* loc)
455 	{
456 		num = a;
457         strcpy(locale, loc);
458 		init();
459 	}
460 
call(UErrorCode * status2)461 	virtual void call(UErrorCode* status2)
462 	{
463         uint32_t listSize = sizeof(collation_strings_escaped)/sizeof(collation_strings_escaped[0]);
464         UErrorCode status = U_ZERO_ERROR;
465         Collator *coll = Collator::createInstance(Locale(locale), status);
466 
467         for(int k = 0; k < num; k++)
468         {
469             uint32_t i, j;
470             for(i=listSize-1; i>=1; i--) {
471                 for(j=0; j<i; j++) {
472                     if(coll->compare(collation_strings[j], collation_strings[j+1]) == UCOL_LESS) {
473                     //cout << "Success!" << endl;
474                      }
475                 }
476             }
477          }
478         delete coll;
479     }
480 
getOperationsPerIteration()481 	virtual long getOperationsPerIteration()
482 	{
483 		return num;
484 	}
485 };
486 
487 class DateFormatPerfTest : public UPerfTest
488 {
489 private:
490 
491 public:
492 
493 	DateFormatPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
494 	~DateFormatPerfTest();
495 	virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par);
496 
497 	UPerfFunction* DateFmt250();
498 	UPerfFunction* DateFmt10000();
499 	UPerfFunction* DateFmt100000();
500 	UPerfFunction* BreakItWord250();
501 	UPerfFunction* BreakItWord10000();
502 	UPerfFunction* BreakItChar250();
503 	UPerfFunction* BreakItChar10000();
504     UPerfFunction* NumFmt10000();
505     UPerfFunction* NumFmt100000();
506     UPerfFunction* Collation10000();
507     UPerfFunction* Collation100000();
508 };
509 
510 #endif // DateFmtPerf
511