1 /*
2 ***********************************************************************
3 * © 2016 and later: Unicode, Inc. and others.
4 * License & terms of use: http://www.unicode.org/copyright.html
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 
getEventsPerIteration()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 
call(UErrorCode * status)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 
getOperationsPerIteration()130     virtual long getOperationsPerIteration()
131     {
132         if(line_mode_==TRUE){
133             return numLines_;
134         }else{
135             return 1;
136         }
137     }
138 
StringPerfFunction(ICUStringPerfFn func,ULine * srcLines,int32_t srcNumLines,UBool uselen)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 
StringPerfFunction(StdStringPerfFn func,ULine * srcLines,int32_t srcNumLines,UBool uselen)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 
StringPerfFunction(ICUStringPerfFn func,UChar * source,int32_t sourceLen,UBool uselen)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 
StringPerfFunction(StdStringPerfFn func,UChar * source,int32_t sourceLen,UBool uselen)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 
~StringPerfFunction()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:
prepareLinesForStd(void)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 
prepareBulkForStd(void)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 
ctor(const UChar * src,int32_t srcLen,UnicodeString s0)391 inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0)
392 {
393     UnicodeString a;
394 }
395 
ctor1(const UChar * src,int32_t srcLen,UnicodeString s0)396 inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0)
397 {
398     UnicodeString b(uTESTCHAR1);
399 }
400 
ctor2(const UChar * src,int32_t srcLen,UnicodeString s0)401 inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0)
402 {
403     UnicodeString c(uEMPTY);
404 }
405 
ctor3(const UChar * src,int32_t srcLen,UnicodeString s0)406 inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0)
407 {
408     UnicodeString d(src,srcLen);
409 }
410 
icu_assign_helper(const UChar * src,int32_t srcLen)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 
assign(const UChar * src,int32_t srcLen,UnicodeString s0)417 inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0)
418 {
419     unistr = icu_assign_helper(src,srcLen);
420 }
421 
assign1(const UChar * src,int32_t srcLen,UnicodeString s0)422 inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0)
423 {
424     unistr.setTo(src, srcLen);
425 }
426 
assign2(const UChar * src,int32_t srcLen,UnicodeString s0)427 inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0)
428 {
429     unistr = s0;
430 }
431 
getch(const UChar * src,int32_t srcLen,UnicodeString s0)432 inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0)
433 {
434     s0.charAt(0);
435 }
436 
437 
catenate(const UChar * src,int32_t srcLen,UnicodeString s0)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 
scan(const UChar * src,int32_t srcLen,UnicodeString s0)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 
scan1(const UChar * src,int32_t srcLen,UnicodeString s0)461 inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0)
462 {
463     scan_idx = uScan_STRING.indexOf(SCAN1,3);
464 }
465 
scan2(const UChar * src,int32_t srcLen,UnicodeString s0)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 
StdLibCtor(const wchar_t * src,int32_t srcLen,stlstring s0)475 inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0)
476 {
477     stlstring a;
478 }
479 
StdLibCtor1(const wchar_t * src,int32_t srcLen,stlstring s0)480 inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0)
481 {
482     stlstring b(simulate);
483 }
484 
StdLibCtor2(const wchar_t * src,int32_t srcLen,stlstring s0)485 inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0)
486 {
487     stlstring c(sEMPTY);
488 }
489 
StdLibCtor3(const wchar_t * src,int32_t srcLen,stlstring s0)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 
stl_assign_helper(const wchar_t * src,int32_t srcLen)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 
StdLibAssign(const wchar_t * src,int32_t srcLen,stlstring s0)505 inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0)
506 {
507     stlstr = stl_assign_helper(src,srcLen);
508 }
509 
StdLibAssign1(const wchar_t * src,int32_t srcLen,stlstring s0)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 
StdLibAssign2(const wchar_t * src,int32_t srcLen,stlstring s0)516 inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0)
517 {
518     stlstr=s0;
519 }
520 
StdLibGetch(const wchar_t * src,int32_t srcLen,stlstring s0)521 inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0)
522 {
523     s0.at(0);
524 }
525 
StdLibCatenate(const wchar_t * src,int32_t srcLen,stlstring s0)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 
StdLibScan(const wchar_t * src,int32_t srcLen,stlstring s0)540 inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0)
541 {
542     scan_idx = (int) sScan_STRING.find('.');
543 }
544 
StdLibScan1(const wchar_t * src,int32_t srcLen,stlstring s0)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 
StdLibScan2(const wchar_t * src,int32_t srcLen,stlstring s0)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