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