1/*
2**********************************************************************
3* Copyright (c) 2002-2006, International Business Machines
4* Corporation and others.  All Rights Reserved.
5**********************************************************************
6*/
7#ifndef _STRINGPERF_H
8#define _STRINGPERF_H
9
10#include <string>
11
12#include "unicode/utypes.h"
13#include "unicode/unistr.h"
14
15#include "unicode/uperf.h"
16
17typedef std::wstring stlstring;
18
19/* Define all constants for test case operations */
20#define MAXNUMLINES	40000	//Max number of lines in a test data file
21#define MAXSRCLEN 20		//Max length of one line. maybe a larger number, but it need more mem
22#define LOOPS 100			//Iterations
23//#define LOOPS 10
24#define catenate_STRLEN 2
25
26const UChar uTESTCHAR1 =  'a';
27const wchar_t wTESTCHAR1 = 'a';
28const UnicodeString uEMPTY;
29const stlstring sEMPTY;
30UnicodeString unistr;
31stlstring stlstr;
32// Simulate construction with a single-char string for basic_string
33wchar_t simulate[2]={wTESTCHAR1, 0};
34
35/* Constants for scan operation */
36U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25);
37const UnicodeString uScan_STRING=UnicodeString(scan_STRING);
38const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data.");
39
40/* global variables or constants for concatenation operation */
41U_STRING_DECL(uCatenate_STR, "!!", 2);
42const stlstring sCatenate_STR=stlstring(L"!!");
43static UnicodeString* catICU;
44static stlstring* catStd;
45UBool bCatenatePrealloc;
46
47/* type defines */
48typedef struct WLine WLine;
49struct  WLine {
50    wchar_t   name[100];
51    int32_t   len;
52}; //struct to store one line of wchar_t string
53
54enum FnType { Fn_ICU, Fn_STD };
55typedef FnType FnType;
56typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0);
57typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0);
58
59
60class StringPerfFunction : public UPerfFunction
61{
62public:
63
64    virtual long getEventsPerIteration(){
65        int loops = LOOPS;
66        if (catICU) { delete catICU;}
67        if (catStd) { delete catStd;}
68
69        if (bCatenatePrealloc) {
70
71            int to_alloc = loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN);
72            catICU = new UnicodeString(to_alloc,'a',0);
73            //catICU = new UnicodeString();
74
75            catStd = new stlstring();
76            //catStd -> reserve(loops * MAXNUMLINES * (MAXSRCLEN + catenate_STRLEN));
77            catStd -> reserve(110000000);
78        } else {
79            catICU = new UnicodeString();
80            catStd = new stlstring();
81        }
82
83        return -1;
84    }
85
86    virtual void call(UErrorCode* status)
87    {
88        if(line_mode_==TRUE){
89            if(uselen_){
90                for(int32_t i = 0; i< numLines_; i++){
91                    if (fnType_==Fn_ICU) {
92                        (*fn1_)(lines_[i].name,lines_[i].len,uS0_[i]);
93                    } else {
94                        (*fn2_)(wlines_[i].name,wlines_[i].len,sS0_[i]);
95                    }
96                }
97            }else{
98                for(int32_t i = 0; i< numLines_; i++){
99                    if (fnType_==Fn_ICU) {
100                        (*fn1_)(lines_[i].name,-1,uS0_[i]);
101                    } else {
102                        (*fn2_)(wlines_[i].name,-1,sS0_[i]);
103                    }
104                }
105            }
106        }else{
107            if(uselen_){
108                if (fnType_==Fn_ICU) {
109                    (*fn1_)(src_,srcLen_,*ubulk_);
110                } else {
111                    (*fn2_)(wsrc_,wsrcLen_,*sbulk_);
112                }
113            }else{
114                if (fnType_==Fn_ICU) {
115                    (*fn1_)(src_,-1,*ubulk_);
116                } else {
117                    (*fn2_)(wsrc_,-1,*sbulk_);
118                }
119            }
120        }
121    }
122
123    virtual long getOperationsPerIteration()
124    {
125        if(line_mode_==TRUE){
126            return numLines_;
127        }else{
128            return 1;
129        }
130    }
131
132    StringPerfFunction(ICUStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen)
133    {
134
135        fn1_ = func;
136        lines_=srcLines;
137        wlines_=NULL;
138        numLines_=srcNumLines;
139        uselen_=uselen;
140        line_mode_=TRUE;
141        src_ = NULL;
142        srcLen_ = 0;
143        wsrc_ = NULL;
144        wsrcLen_ = 0;
145        fnType_ = Fn_ICU;
146
147        uS0_=new UnicodeString[numLines_];
148        for(int32_t i=0; i<numLines_; i++) {
149            uS0_[i]=UnicodeString(lines_[i].name, lines_[i].len);
150        }
151        sS0_=NULL;
152        ubulk_=NULL;
153        sbulk_=NULL;
154    }
155
156    StringPerfFunction(StdStringPerfFn func, ULine* srcLines, int32_t srcNumLines, UBool uselen)
157    {
158
159        fn2_ = func;
160        lines_=srcLines;
161        wlines_=NULL;
162        numLines_=srcNumLines;
163        uselen_=uselen;
164        line_mode_=TRUE;
165        src_ = NULL;
166        srcLen_ = 0;
167        wsrc_ = NULL;
168        wsrcLen_ = 0;
169        fnType_ = Fn_STD;
170
171        uS0_=NULL;
172        ubulk_=NULL;
173        sbulk_=NULL;
174
175        //fillin wlines_[], sS0_[]
176        prepareLinesForStd();
177    }
178
179    StringPerfFunction(ICUStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen)
180    {
181
182        fn1_ = func;
183        lines_=NULL;
184        wlines_=NULL;
185        numLines_=0;
186        uselen_=uselen;
187        line_mode_=FALSE;
188        src_ = new UChar[sourceLen];
189        memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR);
190        srcLen_ = sourceLen;
191        wsrc_ = NULL;
192        wsrcLen_ = 0;
193        fnType_ = Fn_ICU;
194
195        uS0_=NULL;
196        sS0_=NULL;
197        ubulk_=new UnicodeString(src_,srcLen_);
198        sbulk_=NULL;
199    }
200
201    StringPerfFunction(StdStringPerfFn func, UChar* source, int32_t sourceLen, UBool uselen)
202    {
203
204        fn2_ = func;
205        lines_=NULL;
206        wlines_=NULL;
207        numLines_=0;
208        uselen_=uselen;
209        line_mode_=FALSE;
210        src_ = new UChar[sourceLen];
211        memcpy(src_, source, sourceLen * U_SIZEOF_UCHAR);
212        srcLen_ = sourceLen;
213        fnType_ = Fn_STD;
214
215        uS0_=NULL;
216        sS0_=NULL;
217        ubulk_=NULL;
218
219        //fillin wsrc_, sbulk_
220        prepareBulkForStd();
221
222    }
223
224    ~StringPerfFunction()
225    {
226        //free(src_);
227        free(wsrc_);
228        delete[] src_;
229        delete ubulk_;
230        delete sbulk_;
231        delete[] uS0_;
232        delete[] sS0_;
233        delete[] wlines_;
234    }
235
236private:
237    void prepareLinesForStd(void)
238    {
239        UErrorCode err=U_ZERO_ERROR;
240
241        wlines_=new WLine[numLines_];
242        wchar_t ws[100];
243        int32_t wcap = sizeof(ws) / sizeof(*ws);
244        int32_t wl;
245        wchar_t* wcs;
246
247        sS0_=new stlstring[numLines_];
248        for(int32_t i=0; i<numLines_; i++) {
249            if(uselen_) {
250                wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len, &err);
251                memcpy(wlines_[i].name, wcs, wl * sizeof(wchar_t));
252                wlines_[i].len = wl;
253                sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len);
254            } else {
255                wcs = u_strToWCS(ws, wcap, &wl, lines_[i].name, lines_[i].len-1, &err);
256                memcpy(wlines_[i].name, wcs, wl*sizeof(wchar_t));
257                wlines_[i].len = wl;
258                sS0_[i]=stlstring(wlines_[i].name, wlines_[i].len+1);
259            }
260
261            if (U_FAILURE(err)) {
262                return;
263            }
264        }
265
266    }
267
268    void prepareBulkForStd(void)
269    {
270        UErrorCode err=U_ZERO_ERROR;
271
272        const UChar* uSrc = src_;
273        int32_t uSrcLen = srcLen_;
274        wchar_t* wDest = NULL;
275        int32_t wDestLen = 0;
276        int32_t reqLen= 0 ;
277
278        if(uselen_) {
279            /* pre-flight*/
280            u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err);
281
282            if(err == U_BUFFER_OVERFLOW_ERROR){
283                err=U_ZERO_ERROR;
284                wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen));
285                wDestLen = reqLen;
286                u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen,&err);
287            }
288
289            if (U_SUCCESS(err)) {
290                wsrc_ = wDest;
291                wsrcLen_ = wDestLen;
292                sbulk_=new stlstring(wsrc_,wsrcLen_);
293            }
294
295        } else {
296            /* pre-flight*/
297            u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err);
298
299            if(err == U_BUFFER_OVERFLOW_ERROR){
300                err=U_ZERO_ERROR;
301                wDest =(wchar_t*) malloc(sizeof(wchar_t) * (reqLen+1));
302                wDestLen = reqLen+1;
303                u_strToWCS(wDest,wDestLen,&reqLen,uSrc,uSrcLen-1,&err);
304            }
305
306            if (U_SUCCESS(err)) {
307                wsrc_ = wDest;
308                wsrcLen_ = wDestLen;
309                sbulk_=new stlstring(wsrc_);
310            }
311        }
312
313        //free(wDest);
314    }
315
316
317private:
318    ICUStringPerfFn fn1_;
319    StdStringPerfFn fn2_;
320
321    ULine* lines_;
322    WLine* wlines_;
323    int32_t numLines_;
324
325    UBool uselen_;
326    UChar* src_;
327    int32_t srcLen_;
328    wchar_t* wsrc_;
329    int32_t wsrcLen_;
330    UBool line_mode_;
331
332    //added for preparing testing data
333    UnicodeString* uS0_;
334    stlstring* sS0_;
335    UnicodeString* ubulk_;
336    stlstring* sbulk_;
337    FnType fnType_;
338};
339
340
341class StringPerformanceTest : public UPerfTest
342{
343public:
344    StringPerformanceTest(int32_t argc, const char *argv[], UErrorCode &status);
345    ~StringPerformanceTest();
346    virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,
347                                          const char *&name,
348                                          char *par = NULL);
349    UPerfFunction* TestCtor();
350    UPerfFunction* TestCtor1();
351    UPerfFunction* TestCtor2();
352    UPerfFunction* TestCtor3();
353    UPerfFunction* TestAssign();
354    UPerfFunction* TestAssign1();
355    UPerfFunction* TestAssign2();
356    UPerfFunction* TestGetch();
357    UPerfFunction* TestCatenate();
358    UPerfFunction* TestScan();
359    UPerfFunction* TestScan1();
360    UPerfFunction* TestScan2();
361
362    UPerfFunction* TestStdLibCtor();
363    UPerfFunction* TestStdLibCtor1();
364    UPerfFunction* TestStdLibCtor2();
365    UPerfFunction* TestStdLibCtor3();
366    UPerfFunction* TestStdLibAssign();
367    UPerfFunction* TestStdLibAssign1();
368    UPerfFunction* TestStdLibAssign2();
369    UPerfFunction* TestStdLibGetch();
370    UPerfFunction* TestStdLibCatenate();
371    UPerfFunction* TestStdLibScan();
372    UPerfFunction* TestStdLibScan1();
373    UPerfFunction* TestStdLibScan2();
374
375private:
376    long COUNT_;
377    ULine* filelines_;
378    UChar* StrBuffer;
379    int32_t StrBufferLen;
380
381};
382
383
384inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0)
385{
386    UnicodeString a;
387}
388
389inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0)
390{
391    UnicodeString b(uTESTCHAR1);
392}
393
394inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0)
395{
396    UnicodeString c(uEMPTY);
397}
398
399inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0)
400{
401    UnicodeString d(src,srcLen);
402}
403
404inline UnicodeString icu_assign_helper(const UChar* src,int32_t srcLen)
405{
406    if (srcLen==-1) { return src;}
407    else { return UnicodeString(src, srcLen);}
408}
409
410inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0)
411{
412    unistr = icu_assign_helper(src,srcLen);
413}
414
415inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0)
416{
417    unistr.setTo(src, srcLen);
418}
419
420inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0)
421{
422    unistr = s0;
423}
424
425inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0)
426{
427    s0.charAt(0);
428}
429
430
431inline void catenate(const UChar* src,int32_t srcLen, UnicodeString s0)
432{
433    UTimer mystart, mystop;
434    utimer_getTime(&mystart);
435
436    *catICU += s0;
437
438    utimer_getTime(&mystop);
439    double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
440    printf("\nmytime=%f \n", mytime);
441
442    *catICU += uCatenate_STR;
443}
444
445volatile int scan_idx;
446U_STRING_DECL(SCAN1, "123", 3);
447
448inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0)
449{
450    UChar c='.';
451    scan_idx = uScan_STRING.indexOf(c);
452}
453
454inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0)
455{
456    scan_idx = uScan_STRING.indexOf(SCAN1,3);
457}
458
459inline void scan2(const UChar* src,int32_t srcLen, UnicodeString s0)
460{
461    UChar c1='s';
462    UChar c2='m';
463    scan_idx = uScan_STRING.indexOf(c1);
464    scan_idx = uScan_STRING.indexOf(c2);
465}
466
467
468inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0)
469{
470    stlstring a;
471}
472
473inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0)
474{
475    stlstring b(simulate);
476}
477
478inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0)
479{
480    stlstring c(sEMPTY);
481}
482
483inline void StdLibCtor3(const wchar_t* src,int32_t srcLen, stlstring s0)
484{
485    if (srcLen==-1) {
486        stlstring d(src);
487    }else {
488        stlstring d(src, srcLen);
489    }
490}
491
492inline stlstring stl_assign_helper(const wchar_t* src,int32_t srcLen)
493{
494    if (srcLen==-1) { return src;}
495    else { return stlstring(src, srcLen);}
496}
497
498inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0)
499{
500    stlstr = stl_assign_helper(src,srcLen);
501}
502
503inline void StdLibAssign1(const wchar_t* src,int32_t srcLen, stlstring s0)
504{
505    if (srcLen==-1) { stlstr=src;}
506    else { stlstr.assign(src, srcLen);}
507}
508
509inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0)
510{
511    stlstr=s0;
512}
513
514inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0)
515{
516    s0.at(0);
517}
518
519inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0)
520{
521    UTimer mystart, mystop;
522    utimer_getTime(&mystart);
523
524    *catStd += s0;
525    *catStd += sCatenate_STR;
526
527    utimer_getTime(&mystop);
528    double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
529    printf("\nmytime=%f \n", mytime);
530
531}
532
533inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0)
534{
535    scan_idx = (int) sScan_STRING.find('.');
536}
537
538inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0)
539{
540    scan_idx = (int) sScan_STRING.find(L"123");
541}
542
543inline void StdLibScan2(const wchar_t* src,int32_t srcLen, stlstring s0)
544{
545    scan_idx = (int) sScan_STRING.find_first_of(L"sm");
546}
547
548#endif // STRINGPERF_H
549
550