Home | History | Annotate | Download | only in ustrperf
      1 /*
      2 ***********************************************************************
      3 *  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 
     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 
    243 private:
    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 
    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 
    391 inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0)
    392 {
    393     UnicodeString a;
    394 }
    395 
    396 inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0)
    397 {
    398     UnicodeString b(uTESTCHAR1);
    399 }
    400 
    401 inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0)
    402 {
    403     UnicodeString c(uEMPTY);
    404 }
    405 
    406 inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0)
    407 {
    408     UnicodeString d(src,srcLen);
    409 }
    410 
    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 
    417 inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0)
    418 {
    419     unistr = icu_assign_helper(src,srcLen);
    420 }
    421 
    422 inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0)
    423 {
    424     unistr.setTo(src, srcLen);
    425 }
    426 
    427 inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0)
    428 {
    429     unistr = s0;
    430 }
    431 
    432 inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0)
    433 {
    434     s0.charAt(0);
    435 }
    436 
    437 
    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 
    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 
    461 inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0)
    462 {
    463     scan_idx = uScan_STRING.indexOf(SCAN1,3);
    464 }
    465 
    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 
    475 inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0)
    476 {
    477     stlstring a;
    478 }
    479 
    480 inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0)
    481 {
    482     stlstring b(simulate);
    483 }
    484 
    485 inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0)
    486 {
    487     stlstring c(sEMPTY);
    488 }
    489 
    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 
    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 
    505 inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0)
    506 {
    507     stlstr = stl_assign_helper(src,srcLen);
    508 }
    509 
    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 
    516 inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0)
    517 {
    518     stlstr=s0;
    519 }
    520 
    521 inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0)
    522 {
    523     s0.at(0);
    524 }
    525 
    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 
    540 inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0)
    541 {
    542     scan_idx = (int) sScan_STRING.find('.');
    543 }
    544 
    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 
    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