blob: 8021d8e43498df3e4296bdeedc3b4e7b5b994736 [file] [log] [blame]
Frank Tang3e05d9d2021-11-08 14:04:04 -08001/*
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
24typedef 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
33const UChar uTESTCHAR1 = 'a';
34const wchar_t wTESTCHAR1 = 'a';
35const UnicodeString uEMPTY;
36const stlstring sEMPTY;
37UnicodeString unistr;
38stlstring stlstr;
39// Simulate construction with a single-char string for basic_string
40wchar_t simulate[2]={wTESTCHAR1, 0};
41
42/* Constants for scan operation */
43U_STRING_DECL(scan_STRING, "Dot. 123. Some more data.", 25);
44const UnicodeString uScan_STRING=UnicodeString(scan_STRING);
45const stlstring sScan_STRING=stlstring(L"Dot. 123. Some more data.");
46
47/* global variables or constants for concatenation operation */
48U_STRING_DECL(uCatenate_STR, "!!", 2);
49const stlstring sCatenate_STR=stlstring(L"!!");
50static UnicodeString* catICU;
51static stlstring* catStd;
52UBool bCatenatePrealloc;
53
54/* type defines */
55typedef struct WLine WLine;
56struct WLine {
57 wchar_t name[100];
58 int32_t len;
59}; //struct to store one line of wchar_t string
60
61enum FnType { Fn_ICU, Fn_STD };
62typedef FnType FnType;
63typedef void (*ICUStringPerfFn)(const UChar* src,int32_t srcLen, UnicodeString s0);
64typedef void (*StdStringPerfFn)(const wchar_t* src,int32_t srcLen, stlstring s0);
65
66
67class StringPerfFunction : public UPerfFunction
68{
69public:
70
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
93 virtual void call(UErrorCode* status)
94 {
Frank Tang1f164ee2022-11-08 12:31:27 -080095 if(line_mode_==true){
Frank Tang3e05d9d2021-11-08 14:04:04 -080096 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
130 virtual long getOperationsPerIteration()
131 {
Frank Tang1f164ee2022-11-08 12:31:27 -0800132 if(line_mode_==true){
Frank Tang3e05d9d2021-11-08 14:04:04 -0800133 return numLines_;
134 }else{
135 return 1;
136 }
137 }
138
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;
Frank Tang1f164ee2022-11-08 12:31:27 -0800147 line_mode_=true;
Frank Tang3e05d9d2021-11-08 14:04:04 -0800148 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
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;
Frank Tang1f164ee2022-11-08 12:31:27 -0800171 line_mode_=true;
Frank Tang3e05d9d2021-11-08 14:04:04 -0800172 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
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;
Frank Tang1f164ee2022-11-08 12:31:27 -0800194 line_mode_=false;
Frank Tang3e05d9d2021-11-08 14:04:04 -0800195 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
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;
Frank Tang1f164ee2022-11-08 12:31:27 -0800216 line_mode_=false;
Frank Tang3e05d9d2021-11-08 14:04:04 -0800217 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
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
243private:
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
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
324private:
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
348class StringPerformanceTest : public UPerfTest
349{
350public:
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
382private:
383 long COUNT_;
384 ULine* filelines_;
385 UChar* StrBuffer;
386 int32_t StrBufferLen;
387
388};
389
390
391inline void ctor(const UChar* src,int32_t srcLen, UnicodeString s0)
392{
393 UnicodeString a;
394}
395
396inline void ctor1(const UChar* src,int32_t srcLen, UnicodeString s0)
397{
398 UnicodeString b(uTESTCHAR1);
399}
400
401inline void ctor2(const UChar* src,int32_t srcLen, UnicodeString s0)
402{
403 UnicodeString c(uEMPTY);
404}
405
406inline void ctor3(const UChar* src,int32_t srcLen, UnicodeString s0)
407{
408 UnicodeString d(src,srcLen);
409}
410
411inline 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
417inline void assign(const UChar* src,int32_t srcLen, UnicodeString s0)
418{
419 unistr = icu_assign_helper(src,srcLen);
420}
421
422inline void assign1(const UChar* src,int32_t srcLen, UnicodeString s0)
423{
424 unistr.setTo(src, srcLen);
425}
426
427inline void assign2(const UChar* src,int32_t srcLen, UnicodeString s0)
428{
429 unistr = s0;
430}
431
432inline void getch(const UChar* src,int32_t srcLen, UnicodeString s0)
433{
434 s0.charAt(0);
435}
436
437
438inline 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);
Frank Tang3e05d9d2021-11-08 14:04:04 -0800447
448 *catICU += uCatenate_STR;
449}
450
451volatile int scan_idx;
452U_STRING_DECL(SCAN1, "123", 3);
453
454inline void scan(const UChar* src,int32_t srcLen, UnicodeString s0)
455{
456 UChar c='.';
457 scan_idx = uScan_STRING.indexOf(c);
458}
459
460inline void scan1(const UChar* src,int32_t srcLen, UnicodeString s0)
461{
462 scan_idx = uScan_STRING.indexOf(SCAN1,3);
463}
464
465inline void scan2(const UChar* src,int32_t srcLen, UnicodeString s0)
466{
467 UChar c1='s';
468 UChar c2='m';
469 scan_idx = uScan_STRING.indexOf(c1);
470 scan_idx = uScan_STRING.indexOf(c2);
471}
472
473
474inline void StdLibCtor(const wchar_t* src,int32_t srcLen, stlstring s0)
475{
476 stlstring a;
477}
478
479inline void StdLibCtor1(const wchar_t* src,int32_t srcLen, stlstring s0)
480{
481 stlstring b(simulate);
482}
483
484inline void StdLibCtor2(const wchar_t* src,int32_t srcLen, stlstring s0)
485{
486 stlstring c(sEMPTY);
487}
488
489inline void StdLibCtor3(const wchar_t* src,int32_t srcLen, stlstring s0)
490{
491 if (srcLen==-1) {
492 stlstring d(src);
493 }else {
494 stlstring d(src, srcLen);
495 }
496}
497
498inline stlstring stl_assign_helper(const wchar_t* src,int32_t srcLen)
499{
500 if (srcLen==-1) { return src;}
501 else { return stlstring(src, srcLen);}
502}
503
504inline void StdLibAssign(const wchar_t* src,int32_t srcLen, stlstring s0)
505{
506 stlstr = stl_assign_helper(src,srcLen);
507}
508
509inline void StdLibAssign1(const wchar_t* src,int32_t srcLen, stlstring s0)
510{
511 if (srcLen==-1) { stlstr=src;}
512 else { stlstr.assign(src, srcLen);}
513}
514
515inline void StdLibAssign2(const wchar_t* src,int32_t srcLen, stlstring s0)
516{
517 stlstr=s0;
518}
519
520inline void StdLibGetch(const wchar_t* src,int32_t srcLen, stlstring s0)
521{
522 s0.at(0);
523}
524
525inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0)
526{
527 UTimer mystart, mystop;
528 utimer_getTime(&mystart);
529
530 *catStd += s0;
531 *catStd += sCatenate_STR;
532
533 utimer_getTime(&mystop);
534 double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
Frank Tang3e05d9d2021-11-08 14:04:04 -0800535
536}
537
538inline void StdLibScan(const wchar_t* src,int32_t srcLen, stlstring s0)
539{
540 scan_idx = (int) sScan_STRING.find('.');
541}
542
543inline void StdLibScan1(const wchar_t* src,int32_t srcLen, stlstring s0)
544{
545 scan_idx = (int) sScan_STRING.find(L"123");
546}
547
548inline void StdLibScan2(const wchar_t* src,int32_t srcLen, stlstring s0)
549{
550 scan_idx = (int) sScan_STRING.find_first_of(L"sm");
551}
552
553#endif // STRINGPERF_H
554