1 /* 2 ********************************************************************** 3 * Copyright (c) 2002-2006, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 */ 7 #ifndef _STRINGPERF_H 8 #define _STRINGPERF_H 9 10 #include <string> 11 12 #include "unicode/utypes.h" 13 #include "unicode/unistr.h" 14 15 #include "unicode/uperf.h" 16 17 typedef std::wstring stlstring; 18 19 /* Define all constants for test case operations */ 20 #define MAXNUMLINES 40000 //Max number of lines in a test data file 21 #define MAXSRCLEN 20 //Max length of one line. maybe a larger number, but it need more mem 22 #define LOOPS 100 //Iterations 23 //#define LOOPS 10 24 #define catenate_STRLEN 2 25 26 const UChar uTESTCHAR1 = 'a'; 27 const wchar_t wTESTCHAR1 = 'a'; 28 const UnicodeString uEMPTY; 29 const stlstring sEMPTY; 30 UnicodeString unistr; 31 stlstring stlstr; 32 // Simulate construction with a single-char string for basic_string 33 wchar_t simulate[2]={wTESTCHAR1, 0}; 34 35 /* Constants for scan operation */ 36 U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25); 37 const UnicodeString uScan_STRING=UnicodeString(scan_STRING); 38 const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data."); 39 40 /* global variables or constants for concatenation operation */ 41 U_STRING_DECL(uCatenate_STR, "!!", 2); 42 const stlstring sCatenate_STR=stlstring(L"!!"); 43 static UnicodeString* catICU; 44 static stlstring* catStd; 45 UBool bCatenatePrealloc; 46 47 /* type defines */ 48 typedef struct WLine WLine; 49 struct WLine { 50 wchar_t name[100]; 51 int32_t len; 52 }; //struct to store one line of wchar_t string 53 54 enum FnType { Fn_ICU, Fn_STD }; 55 typedef FnType FnType; 56 typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0); 57 typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0); 58 59 60 class StringPerfFunction : public UPerfFunction 61 { 62 public: 63 64 virtual long getEventsPerIteration(){ 65 int loops = LOOPS; 66 if (catICU) { delete catICU;} 67 if (catStd) { delete catStd;} 68 69 if (bCatenatePrealloc) { 70 71 int to_alloc = loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN); 72 catICU = new UnicodeString(to_alloc,'a',0); 73 //catICU = new UnicodeString(); 74 75 catStd = new stlstring(); 76 //catStd -> reserve(loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN)); 77 catStd -> reserve(110000000); 78 } else { 79 catICU = new UnicodeString(); 80 catStd = new stlstring(); 81 } 82 83 return -1; 84 } 85 86 virtual void call(UErrorCode* status) 87 { 88 if(line_mode_==TRUE){ 89 if(uselen_){ 90 for(int32_t i = 0; i< numLines_; i++){ 91 if (fnType_==Fn_ICU) { 92 (*fn1_)(lines_[i].name,lines_[i].len,uS0_[i]); 93 } else { 94 (*fn2_)(wlines_[i].name,wlines_[i].len,sS0_[i]); 95 } 96 } 97 }else{ 98 for(int32_t i = 0; i< numLines_; i++){ 99 if (fnType_==Fn_ICU) { 100 (*fn1_)(lines_[i].name,-1,uS0_[i]); 101 } else { 102 (*fn2_)(wlines_[i].name,-1,sS0_[i]); 103 } 104 } 105 } 106 }else{ 107 if(uselen_){ 108 if (fnType_==Fn_ICU) { 109 (*fn1_)(src_,srcLen_,*ubulk_); 110 } else { 111 (*fn2_)(wsrc_,wsrcLen_,*sbulk_); 112 } 113 }else{ 114 if (fnType_==Fn_ICU) { 115 (*fn1_)(src_,-1,*ubulk_); 116 } else { 117 (*fn2_)(wsrc_,-1,*sbulk_); 118 } 119 } 120 } 121 } 122 123 virtual long getOperationsPerIteration() 124 { 125 if(line_mode_==TRUE){ 126 return numLines_; 127 }else{ 128 return 1; 129 } 130 } 131 132 StringPerfFunction(ICUStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen) 133 { 134 135 fn1_ = func; 136 lines_=srcLines; 137 wlines_=NULL; 138 numLines_=srcNumLines; 139 uselen_=uselen; 140 line_mode_=TRUE; 141 src_ = NULL; 142 srcLen_ = 0; 143 wsrc_ = NULL; 144 wsrcLen_ = 0; 145 fnType_ = Fn_ICU; 146 147 uS0_=new UnicodeString[numLines_]; 148 for(int32_t i=0; i<numLines_; i++) { 149 uS0_[i]=UnicodeString(lines_[i].name, lines_[i].len); 150 } 151 sS0_=NULL; 152 ubulk_=NULL; 153 sbulk_=NULL; 154 } 155 156 StringPerfFunction(StdStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen) 157 { 158 159 fn2_ = func; 160 lines_=srcLines; 161 wlines_=NULL; 162 numLines_=srcNumLines; 163 uselen_=uselen; 164 line_mode_=TRUE; 165 src_ = NULL; 166 srcLen_ = 0; 167 wsrc_ = NULL; 168 wsrcLen_ = 0; 169 fnType_ = Fn_STD; 170 171 uS0_=NULL; 172 ubulk_=NULL; 173 sbulk_=NULL; 174 175 //fillin wlines_[], sS0_[] 176 prepareLinesForStd(); 177 } 178 179 StringPerfFunction(ICUStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen) 180 { 181 182 fn1_ = func; 183 lines_=NULL; 184 wlines_=NULL; 185 numLines_=0; 186 uselen_=uselen; 187 line_mode_=FALSE; 188 src_ = new UChar[sourceLen]; 189 memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR); 190 srcLen_ = sourceLen; 191 wsrc_ = NULL; 192 wsrcLen_ = 0; 193 fnType_ = Fn_ICU; 194 195 uS0_=NULL; 196 sS0_=NULL; 197 ubulk_=new UnicodeString(src_,srcLen_); 198 sbulk_=NULL; 199 } 200 201 StringPerfFunction(StdStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen) 202 { 203 204 fn2_ = func; 205 lines_=NULL; 206 wlines_=NULL; 207 numLines_=0; 208 uselen_=uselen; 209 line_mode_=FALSE; 210 src_ = new UChar[sourceLen]; 211 memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR); 212 srcLen_ = sourceLen; 213 fnType_ = Fn_STD; 214 215 uS0_=NULL; 216 sS0_=NULL; 217 ubulk_=NULL; 218 219 //fillin wsrc_, sbulk_ 220 prepareBulkForStd(); 221 222 } 223 224 ~StringPerfFunction() 225 { 226 //free(src_); 227 free(wsrc_); 228 delete[] src_; 229 delete ubulk_; 230 delete sbulk_; 231 delete[] uS0_; 232 delete[] sS0_; 233 delete[] wlines_; 234 } 235 236 private: 237 void prepareLinesForStd(void) 238 { 239 UErrorCode err=U_ZERO_ERROR; 240 241 wlines_=new WLine[numLines_]; 242 wchar_t ws[100]; 243 int32_t wcap = sizeof(ws) / sizeof(*ws); 244 int32_t wl; 245 wchar_t* wcs; 246 247 sS0_=new stlstring[numLines_]; 248 for(int32_t i=0; i<numLines_; i++) { 249 if(uselen_) { 250 wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len, &err); 251 memcpy(wlines_[i].name, wcs, wl * sizeof(wchar_t)); 252 wlines_[i].len = wl; 253 sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len); 254 } else { 255 wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len-1, &err); 256 memcpy(wlines_[i].name, wcs, wl*sizeof(wchar_t)); 257 wlines_[i].len = wl; 258 sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len+1); 259 } 260 261 if (U_FAILURE(err)) { 262 return; 263 } 264 } 265 266 } 267 268 void prepareBulkForStd(void) 269 { 270 UErrorCode err=U_ZERO_ERROR; 271 272 const UChar* uSrc = src_; 273 int32_t uSrcLen = srcLen_; 274 wchar_t* wDest = NULL; 275 int32_t wDestLen = 0; 276 int32_t reqLen= 0 ; 277 278 if(uselen_) { 279 /* pre-flight*/ 280 u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err); 281 282 if(err == U_BUFFER_OVERFLOW_ERROR){ 283 err=U_ZERO_ERROR; 284 wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen)); 285 wDestLen = reqLen; 286 u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err); 287 } 288 289 if (U_SUCCESS(err)) { 290 wsrc_ = wDest; 291 wsrcLen_ = wDestLen; 292 sbulk_=new stlstring(wsrc_,wsrcLen_); 293 } 294 295 } else { 296 /* pre-flight*/ 297 u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err); 298 299 if(err == U_BUFFER_OVERFLOW_ERROR){ 300 err=U_ZERO_ERROR; 301 wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen+1)); 302 wDestLen = reqLen+1; 303 u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err); 304 } 305 306 if (U_SUCCESS(err)) { 307 wsrc_ = wDest; 308 wsrcLen_ = wDestLen; 309 sbulk_=new stlstring(wsrc_); 310 } 311 } 312 313 //free(wDest); 314 } 315 316 317 private: 318 ICUStringPerfFn fn1_; 319 StdStringPerfFn fn2_; 320 321 ULine* lines_; 322 WLine* wlines_; 323 int32_t numLines_; 324 325 UBool uselen_; 326 UChar* src_; 327 int32_t srcLen_; 328 wchar_t* wsrc_; 329 int32_t wsrcLen_; 330 UBool line_mode_; 331 332 //added for preparing testing data 333 UnicodeString* uS0_; 334 stlstring* sS0_; 335 UnicodeString* ubulk_; 336 stlstring* sbulk_; 337 FnType fnType_; 338 }; 339 340 341 class StringPerformanceTest : public UPerfTest 342 { 343 public: 344 StringPerformanceTest(int32_t argc, const char *argv[], UErrorCode &status); 345 ~StringPerformanceTest(); 346 virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec, 347 const char *&name, 348 char *par = NULL); 349 UPerfFunction* TestCtor(); 350 UPerfFunction* TestCtor1(); 351 UPerfFunction* TestCtor2(); 352 UPerfFunction* TestCtor3(); 353 UPerfFunction* TestAssign(); 354 UPerfFunction* TestAssign1(); 355 UPerfFunction* TestAssign2(); 356 UPerfFunction* TestGetch(); 357 UPerfFunction* TestCatenate(); 358 UPerfFunction* TestScan(); 359 UPerfFunction* TestScan1(); 360 UPerfFunction* TestScan2(); 361 362 UPerfFunction* TestStdLibCtor(); 363 UPerfFunction* TestStdLibCtor1(); 364 UPerfFunction* TestStdLibCtor2(); 365 UPerfFunction* TestStdLibCtor3(); 366 UPerfFunction* TestStdLibAssign(); 367 UPerfFunction* TestStdLibAssign1(); 368 UPerfFunction* TestStdLibAssign2(); 369 UPerfFunction* TestStdLibGetch(); 370 UPerfFunction* TestStdLibCatenate(); 371 UPerfFunction* TestStdLibScan(); 372 UPerfFunction* TestStdLibScan1(); 373 UPerfFunction* TestStdLibScan2(); 374 375 private: 376 long COUNT_; 377 ULine* filelines_; 378 UChar* StrBuffer; 379 int32_t StrBufferLen; 380 381 }; 382 383 384 inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0) 385 { 386 UnicodeString a; 387 } 388 389 inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0) 390 { 391 UnicodeString b(uTESTCHAR1); 392 } 393 394 inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0) 395 { 396 UnicodeString c(uEMPTY); 397 } 398 399 inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0) 400 { 401 UnicodeString d(src,srcLen); 402 } 403 404 inline UnicodeString icu_assign_helper(const UChar* src,int32_t srcLen) 405 { 406 if (srcLen==-1) { return src;} 407 else { return UnicodeString(src, srcLen);} 408 } 409 410 inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0) 411 { 412 unistr = icu_assign_helper(src,srcLen); 413 } 414 415 inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0) 416 { 417 unistr.setTo(src, srcLen); 418 } 419 420 inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0) 421 { 422 unistr = s0; 423 } 424 425 inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0) 426 { 427 s0.charAt(0); 428 } 429 430 431 inline void catenate(const UChar* src,int32_t srcLen, UnicodeString s0) 432 { 433 UTimer mystart, mystop; 434 utimer_getTime(&mystart); 435 436 *catICU += s0; 437 438 utimer_getTime(&mystop); 439 double mytime = utimer_getDeltaSeconds(&mystart,&mystop); 440 printf("\nmytime=%f \n", mytime); 441 442 *catICU += uCatenate_STR; 443 } 444 445 volatile int scan_idx; 446 U_STRING_DECL(SCAN1, "123", 3); 447 448 inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0) 449 { 450 UChar c='.'; 451 scan_idx = uScan_STRING.indexOf(c); 452 } 453 454 inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0) 455 { 456 scan_idx = uScan_STRING.indexOf(SCAN1,3); 457 } 458 459 inline void scan2(const UChar* src,int32_t srcLen, UnicodeString s0) 460 { 461 UChar c1='s'; 462 UChar c2='m'; 463 scan_idx = uScan_STRING.indexOf(c1); 464 scan_idx = uScan_STRING.indexOf(c2); 465 } 466 467 468 inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0) 469 { 470 stlstring a; 471 } 472 473 inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0) 474 { 475 stlstring b(simulate); 476 } 477 478 inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0) 479 { 480 stlstring c(sEMPTY); 481 } 482 483 inline void StdLibCtor3(const wchar_t* src,int32_t srcLen, stlstring s0) 484 { 485 if (srcLen==-1) { 486 stlstring d(src); 487 }else { 488 stlstring d(src, srcLen); 489 } 490 } 491 492 inline stlstring stl_assign_helper(const wchar_t* src,int32_t srcLen) 493 { 494 if (srcLen==-1) { return src;} 495 else { return stlstring(src, srcLen);} 496 } 497 498 inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0) 499 { 500 stlstr = stl_assign_helper(src,srcLen); 501 } 502 503 inline void StdLibAssign1(const wchar_t* src,int32_t srcLen, stlstring s0) 504 { 505 if (srcLen==-1) { stlstr=src;} 506 else { stlstr.assign(src, srcLen);} 507 } 508 509 inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0) 510 { 511 stlstr=s0; 512 } 513 514 inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0) 515 { 516 s0.at(0); 517 } 518 519 inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0) 520 { 521 UTimer mystart, mystop; 522 utimer_getTime(&mystart); 523 524 *catStd += s0; 525 *catStd += sCatenate_STR; 526 527 utimer_getTime(&mystop); 528 double mytime = utimer_getDeltaSeconds(&mystart,&mystop); 529 printf("\nmytime=%f \n", mytime); 530 531 } 532 533 inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0) 534 { 535 scan_idx = (int) sScan_STRING.find('.'); 536 } 537 538 inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0) 539 { 540 scan_idx = (int) sScan_STRING.find(L"123"); 541 } 542 543 inline void StdLibScan2(const wchar_t* src,int32_t srcLen, stlstring s0) 544 { 545 scan_idx = (int) sScan_STRING.find_first_of(L"sm"); 546 } 547 548 #endif // STRINGPERF_H 549 550