/* ********************************************************************** * Copyright (c) 2002-2011, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ #ifndef _STRINGPERF_H #define _STRINGPERF_H #include "unicode/utypes.h" #include "unicode/unistr.h" #include "unicode/uperf.h" #include <string.h> #include <stdio.h> #include <stdlib.h> typedef std::wstring stlstring; /* Define all constants for test case operations */ #define MAXNUMLINES 40000 //Max number of lines in a test data file #define MAXSRCLEN 20 //Max length of one line. maybe a larger number, but it need more mem #define LOOPS 100 //Iterations //#define LOOPS 10 #define catenate_STRLEN 2 const UChar uTESTCHAR1 = 'a'; const wchar_t wTESTCHAR1 = 'a'; const UnicodeString uEMPTY; const stlstring sEMPTY; UnicodeString unistr; stlstring stlstr; // Simulate construction with a single-char string for basic_string wchar_t simulate[2]={wTESTCHAR1, 0}; /* Constants for scan operation */ U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25); const UnicodeString uScan_STRING=UnicodeString(scan_STRING); const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data."); /* global variables or constants for concatenation operation */ U_STRING_DECL(uCatenate_STR, "!!", 2); const stlstring sCatenate_STR=stlstring(L"!!"); static UnicodeString* catICU; static stlstring* catStd; UBool bCatenatePrealloc; /* type defines */ typedef struct WLine WLine; struct WLine { wchar_t name[100]; int32_t len; }; //struct to store one line of wchar_t string enum FnType { Fn_ICU, Fn_STD }; typedef FnType FnType; typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0); typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0); class StringPerfFunction : public UPerfFunction { public: virtual long getEventsPerIteration(){ int loops = LOOPS; if (catICU) { delete catICU;} if (catStd) { delete catStd;} if (bCatenatePrealloc) { int to_alloc = loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN); catICU = new UnicodeString(to_alloc,'a',0); //catICU = new UnicodeString(); catStd = new stlstring(); //catStd -> reserve(loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN)); catStd -> reserve(110000000); } else { catICU = new UnicodeString(); catStd = new stlstring(); } return -1; } virtual void call(UErrorCode* status) { if(line_mode_==TRUE){ if(uselen_){ for(int32_t i = 0; i< numLines_; i++){ if (fnType_==Fn_ICU) { (*fn1_)(lines_[i].name,lines_[i].len,uS0_[i]); } else { (*fn2_)(wlines_[i].name,wlines_[i].len,sS0_[i]); } } }else{ for(int32_t i = 0; i< numLines_; i++){ if (fnType_==Fn_ICU) { (*fn1_)(lines_[i].name,-1,uS0_[i]); } else { (*fn2_)(wlines_[i].name,-1,sS0_[i]); } } } }else{ if(uselen_){ if (fnType_==Fn_ICU) { (*fn1_)(src_,srcLen_,*ubulk_); } else { (*fn2_)(wsrc_,wsrcLen_,*sbulk_); } }else{ if (fnType_==Fn_ICU) { (*fn1_)(src_,-1,*ubulk_); } else { (*fn2_)(wsrc_,-1,*sbulk_); } } } } virtual long getOperationsPerIteration() { if(line_mode_==TRUE){ return numLines_; }else{ return 1; } } StringPerfFunction(ICUStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen) { fn1_ = func; lines_=srcLines; wlines_=NULL; numLines_=srcNumLines; uselen_=uselen; line_mode_=TRUE; src_ = NULL; srcLen_ = 0; wsrc_ = NULL; wsrcLen_ = 0; fnType_ = Fn_ICU; uS0_=new UnicodeString[numLines_]; for(int32_t i=0; i<numLines_; i++) { uS0_[i]=UnicodeString(lines_[i].name, lines_[i].len); } sS0_=NULL; ubulk_=NULL; sbulk_=NULL; } StringPerfFunction(StdStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen) { fn2_ = func; lines_=srcLines; wlines_=NULL; numLines_=srcNumLines; uselen_=uselen; line_mode_=TRUE; src_ = NULL; srcLen_ = 0; wsrc_ = NULL; wsrcLen_ = 0; fnType_ = Fn_STD; uS0_=NULL; ubulk_=NULL; sbulk_=NULL; //fillin wlines_[], sS0_[] prepareLinesForStd(); } StringPerfFunction(ICUStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen) { fn1_ = func; lines_=NULL; wlines_=NULL; numLines_=0; uselen_=uselen; line_mode_=FALSE; src_ = new UChar[sourceLen]; memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR); srcLen_ = sourceLen; wsrc_ = NULL; wsrcLen_ = 0; fnType_ = Fn_ICU; uS0_=NULL; sS0_=NULL; ubulk_=new UnicodeString(src_,srcLen_); sbulk_=NULL; } StringPerfFunction(StdStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen) { fn2_ = func; lines_=NULL; wlines_=NULL; numLines_=0; uselen_=uselen; line_mode_=FALSE; src_ = new UChar[sourceLen]; memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR); srcLen_ = sourceLen; fnType_ = Fn_STD; uS0_=NULL; sS0_=NULL; ubulk_=NULL; //fillin wsrc_, sbulk_ prepareBulkForStd(); } ~StringPerfFunction() { //free(src_); free(wsrc_); delete[] src_; delete ubulk_; delete sbulk_; delete[] uS0_; delete[] sS0_; delete[] wlines_; } private: void prepareLinesForStd(void) { UErrorCode err=U_ZERO_ERROR; wlines_=new WLine[numLines_]; wchar_t ws[100]; int32_t wcap = sizeof(ws) / sizeof(*ws); int32_t wl; wchar_t* wcs; sS0_=new stlstring[numLines_]; for(int32_t i=0; i<numLines_; i++) { if(uselen_) { wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len, &err); memcpy(wlines_[i].name, wcs, wl * sizeof(wchar_t)); wlines_[i].len = wl; sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len); } else { wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len-1, &err); memcpy(wlines_[i].name, wcs, wl*sizeof(wchar_t)); wlines_[i].len = wl; sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len+1); } if (U_FAILURE(err)) { return; } } } void prepareBulkForStd(void) { UErrorCode err=U_ZERO_ERROR; const UChar* uSrc = src_; int32_t uSrcLen = srcLen_; wchar_t* wDest = NULL; int32_t wDestLen = 0; int32_t reqLen= 0 ; if(uselen_) { /* pre-flight*/ u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err); if(err == U_BUFFER_OVERFLOW_ERROR){ err=U_ZERO_ERROR; wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen)); wDestLen = reqLen; u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err); } if (U_SUCCESS(err)) { wsrc_ = wDest; wsrcLen_ = wDestLen; sbulk_=new stlstring(wsrc_,wsrcLen_); } } else { /* pre-flight*/ u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err); if(err == U_BUFFER_OVERFLOW_ERROR){ err=U_ZERO_ERROR; wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen+1)); wDestLen = reqLen+1; u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err); } if (U_SUCCESS(err)) { wsrc_ = wDest; wsrcLen_ = wDestLen; sbulk_=new stlstring(wsrc_); } } //free(wDest); } private: ICUStringPerfFn fn1_; StdStringPerfFn fn2_; ULine* lines_; WLine* wlines_; int32_t numLines_; UBool uselen_; UChar* src_; int32_t srcLen_; wchar_t* wsrc_; int32_t wsrcLen_; UBool line_mode_; //added for preparing testing data UnicodeString* uS0_; stlstring* sS0_; UnicodeString* ubulk_; stlstring* sbulk_; FnType fnType_; }; class StringPerformanceTest : public UPerfTest { public: StringPerformanceTest(int32_t argc, const char *argv[], UErrorCode &status); ~StringPerformanceTest(); virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL); UPerfFunction* TestCtor(); UPerfFunction* TestCtor1(); UPerfFunction* TestCtor2(); UPerfFunction* TestCtor3(); UPerfFunction* TestAssign(); UPerfFunction* TestAssign1(); UPerfFunction* TestAssign2(); UPerfFunction* TestGetch(); UPerfFunction* TestCatenate(); UPerfFunction* TestScan(); UPerfFunction* TestScan1(); UPerfFunction* TestScan2(); UPerfFunction* TestStdLibCtor(); UPerfFunction* TestStdLibCtor1(); UPerfFunction* TestStdLibCtor2(); UPerfFunction* TestStdLibCtor3(); UPerfFunction* TestStdLibAssign(); UPerfFunction* TestStdLibAssign1(); UPerfFunction* TestStdLibAssign2(); UPerfFunction* TestStdLibGetch(); UPerfFunction* TestStdLibCatenate(); UPerfFunction* TestStdLibScan(); UPerfFunction* TestStdLibScan1(); UPerfFunction* TestStdLibScan2(); private: long COUNT_; ULine* filelines_; UChar* StrBuffer; int32_t StrBufferLen; }; inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0) { UnicodeString a; } inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0) { UnicodeString b(uTESTCHAR1); } inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0) { UnicodeString c(uEMPTY); } inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0) { UnicodeString d(src,srcLen); } inline UnicodeString icu_assign_helper(const UChar* src,int32_t srcLen) { if (srcLen==-1) { return src;} else { return UnicodeString(src, srcLen);} } inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0) { unistr = icu_assign_helper(src,srcLen); } inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0) { unistr.setTo(src, srcLen); } inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0) { unistr = s0; } inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0) { s0.charAt(0); } inline void catenate(const UChar* src,int32_t srcLen, UnicodeString s0) { UTimer mystart, mystop; utimer_getTime(&mystart); *catICU += s0; utimer_getTime(&mystop); double mytime = utimer_getDeltaSeconds(&mystart,&mystop); printf("\nmytime=%f \n", mytime); *catICU += uCatenate_STR; } volatile int scan_idx; U_STRING_DECL(SCAN1, "123", 3); inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0) { UChar c='.'; scan_idx = uScan_STRING.indexOf(c); } inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0) { scan_idx = uScan_STRING.indexOf(SCAN1,3); } inline void scan2(const UChar* src,int32_t srcLen, UnicodeString s0) { UChar c1='s'; UChar c2='m'; scan_idx = uScan_STRING.indexOf(c1); scan_idx = uScan_STRING.indexOf(c2); } inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0) { stlstring a; } inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0) { stlstring b(simulate); } inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0) { stlstring c(sEMPTY); } inline void StdLibCtor3(const wchar_t* src,int32_t srcLen, stlstring s0) { if (srcLen==-1) { stlstring d(src); }else { stlstring d(src, srcLen); } } inline stlstring stl_assign_helper(const wchar_t* src,int32_t srcLen) { if (srcLen==-1) { return src;} else { return stlstring(src, srcLen);} } inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0) { stlstr = stl_assign_helper(src,srcLen); } inline void StdLibAssign1(const wchar_t* src,int32_t srcLen, stlstring s0) { if (srcLen==-1) { stlstr=src;} else { stlstr.assign(src, srcLen);} } inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0) { stlstr=s0; } inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0) { s0.at(0); } inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0) { UTimer mystart, mystop; utimer_getTime(&mystart); *catStd += s0; *catStd += sCatenate_STR; utimer_getTime(&mystop); double mytime = utimer_getDeltaSeconds(&mystart,&mystop); printf("\nmytime=%f \n", mytime); } inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0) { scan_idx = (int) sScan_STRING.find('.'); } inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0) { scan_idx = (int) sScan_STRING.find(L"123"); } inline void StdLibScan2(const wchar_t* src,int32_t srcLen, stlstring s0) { scan_idx = (int) sScan_STRING.find_first_of(L"sm"); } #endif // STRINGPERF_H