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