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 24typedef 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 33const UChar uTESTCHAR1 = 'a'; 34const wchar_t wTESTCHAR1 = 'a'; 35const UnicodeString uEMPTY; 36const stlstring sEMPTY; 37UnicodeString unistr; 38stlstring stlstr; 39// Simulate construction with a single-char string for basic_string 40wchar_t simulate[2]={wTESTCHAR1, 0}; 41 42/* Constants for scan operation */ 43U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25); 44const UnicodeString uScan_STRING=UnicodeString(scan_STRING); 45const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data."); 46 47/* global variables or constants for concatenation operation */ 48U_STRING_DECL(uCatenate_STR, "!!", 2); 49const stlstring sCatenate_STR=stlstring(L"!!"); 50static UnicodeString* catICU; 51static stlstring* catStd; 52UBool bCatenatePrealloc; 53 54/* type defines */ 55typedef struct WLine WLine; 56struct WLine { 57 wchar_t name[100]; 58 int32_t len; 59}; //struct to store one line of wchar_t string 60 61enum FnType { Fn_ICU, Fn_STD }; 62typedef FnType FnType; 63typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0); 64typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0); 65 66 67class StringPerfFunction : public UPerfFunction 68{ 69public: 70 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 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 130 virtual long getOperationsPerIteration() 131 { 132 if(line_mode_==TRUE){ 133 return numLines_; 134 }else{ 135 return 1; 136 } 137 } 138 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 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 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 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 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 243private: 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 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 324private: 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 348class StringPerformanceTest : public UPerfTest 349{ 350public: 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 382private: 383 long COUNT_; 384 ULine* filelines_; 385 UChar* StrBuffer; 386 int32_t StrBufferLen; 387 388}; 389 390 391inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0) 392{ 393 UnicodeString a; 394} 395 396inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0) 397{ 398 UnicodeString b(uTESTCHAR1); 399} 400 401inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0) 402{ 403 UnicodeString c(uEMPTY); 404} 405 406inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0) 407{ 408 UnicodeString d(src,srcLen); 409} 410 411inline 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 417inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0) 418{ 419 unistr = icu_assign_helper(src,srcLen); 420} 421 422inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0) 423{ 424 unistr.setTo(src, srcLen); 425} 426 427inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0) 428{ 429 unistr = s0; 430} 431 432inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0) 433{ 434 s0.charAt(0); 435} 436 437 438inline 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 452volatile int scan_idx; 453U_STRING_DECL(SCAN1, "123", 3); 454 455inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0) 456{ 457 UChar c='.'; 458 scan_idx = uScan_STRING.indexOf(c); 459} 460 461inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0) 462{ 463 scan_idx = uScan_STRING.indexOf(SCAN1,3); 464} 465 466inline 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 475inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0) 476{ 477 stlstring a; 478} 479 480inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0) 481{ 482 stlstring b(simulate); 483} 484 485inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0) 486{ 487 stlstring c(sEMPTY); 488} 489 490inline 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 499inline 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 505inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0) 506{ 507 stlstr = stl_assign_helper(src,srcLen); 508} 509 510inline 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 516inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0) 517{ 518 stlstr=s0; 519} 520 521inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0) 522{ 523 s0.at(0); 524} 525 526inline 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 540inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0) 541{ 542 scan_idx = (int) sScan_STRING.find('.'); 543} 544 545inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0) 546{ 547 scan_idx = (int) sScan_STRING.find(L"123"); 548} 549 550inline 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