Home | History | Annotate | Download | only in ustrperf
      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