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 19typedef 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 28const UChar uTESTCHAR1 = 'a'; 29const wchar_t wTESTCHAR1 = 'a'; 30const UnicodeString uEMPTY; 31const stlstring sEMPTY; 32UnicodeString unistr; 33stlstring stlstr; 34// Simulate construction with a single-char string for basic_string 35wchar_t simulate[2]={wTESTCHAR1, 0}; 36 37/* Constants for scan operation */ 38U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25); 39const UnicodeString uScan_STRING=UnicodeString(scan_STRING); 40const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data."); 41 42/* global variables or constants for concatenation operation */ 43U_STRING_DECL(uCatenate_STR, "!!", 2); 44const stlstring sCatenate_STR=stlstring(L"!!"); 45static UnicodeString* catICU; 46static stlstring* catStd; 47UBool bCatenatePrealloc; 48 49/* type defines */ 50typedef struct WLine WLine; 51struct WLine { 52 wchar_t name[100]; 53 int32_t len; 54}; //struct to store one line of wchar_t string 55 56enum FnType { Fn_ICU, Fn_STD }; 57typedef FnType FnType; 58typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0); 59typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0); 60 61 62class StringPerfFunction : public UPerfFunction 63{ 64public: 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 238private: 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 319private: 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 343class StringPerformanceTest : public UPerfTest 344{ 345public: 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 377private: 378 long COUNT_; 379 ULine* filelines_; 380 UChar* StrBuffer; 381 int32_t StrBufferLen; 382 383}; 384 385 386inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0) 387{ 388 UnicodeString a; 389} 390 391inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0) 392{ 393 UnicodeString b(uTESTCHAR1); 394} 395 396inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0) 397{ 398 UnicodeString c(uEMPTY); 399} 400 401inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0) 402{ 403 UnicodeString d(src,srcLen); 404} 405 406inline 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 412inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0) 413{ 414 unistr = icu_assign_helper(src,srcLen); 415} 416 417inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0) 418{ 419 unistr.setTo(src, srcLen); 420} 421 422inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0) 423{ 424 unistr = s0; 425} 426 427inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0) 428{ 429 s0.charAt(0); 430} 431 432 433inline 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 447volatile int scan_idx; 448U_STRING_DECL(SCAN1, "123", 3); 449 450inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0) 451{ 452 UChar c='.'; 453 scan_idx = uScan_STRING.indexOf(c); 454} 455 456inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0) 457{ 458 scan_idx = uScan_STRING.indexOf(SCAN1,3); 459} 460 461inline 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 470inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0) 471{ 472 stlstring a; 473} 474 475inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0) 476{ 477 stlstring b(simulate); 478} 479 480inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0) 481{ 482 stlstring c(sEMPTY); 483} 484 485inline 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 494inline 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 500inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0) 501{ 502 stlstr = stl_assign_helper(src,srcLen); 503} 504 505inline 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 511inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0) 512{ 513 stlstr=s0; 514} 515 516inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0) 517{ 518 s0.at(0); 519} 520 521inline 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 535inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0) 536{ 537 scan_idx = (int) sScan_STRING.find('.'); 538} 539 540inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0) 541{ 542 scan_idx = (int) sScan_STRING.find(L"123"); 543} 544 545inline 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