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
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