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