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-2014, International Business Machines
8 * Corporation and others. All Rights Reserved.
9 ***********************************************************************
10 * file name: utrie2perf.cpp
12 * tab size: 8 (not used)
15 * created on: 2008sep07
16 * created by: Markus W. Scherer
18 * Performance test program for UTrie2.
23 #include "unicode/uchar.h"
24 #include "unicode/unorm.h"
25 #include "unicode/uperf.h"
29 // Left over from when icu/branches/markus/utf8 could use both old UTrie
30 // and new UTrie2, switched with #if in unorm.cpp and ubidi_props.c.
31 // Comparative benchmarks were done in that branch on revision r24630
34 unorm_initUTrie2(UErrorCode
*pErrorCode
);
37 ubidi_initUTrie2(UErrorCode
*pErrorCode
);
47 class UTrie2PerfTest
: public UPerfTest
{
49 UTrie2PerfTest(int32_t argc
, const char *argv
[], UErrorCode
&status
)
50 : UPerfTest(argc
, argv
, NULL
, 0, "", status
),
51 utf8(NULL
), utf8Length(0), countInputCodePoints(0) {
52 if (U_SUCCESS(status
)) {
53 #if 0 // See comment at unorm_initUTrie2() forward declaration.
54 unorm_initUTrie2(&status
);
55 ubidi_initUTrie2(&status
);
58 UPerfTest::getBuffer(inputLength
, status
);
59 if(U_SUCCESS(status
) && inputLength
>0) {
60 countInputCodePoints
= u_countChar32(buffer
, bufferLen
);
62 // Preflight the UTF-8 length and allocate utf8.
63 u_strToUTF8(NULL
, 0, &utf8Length
, buffer
, bufferLen
, &status
);
64 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
65 utf8
=(char *)malloc(utf8Length
);
68 u_strToUTF8(utf8
, utf8Length
, NULL
, buffer
, bufferLen
, &status
);
70 status
=U_MEMORY_ALLOCATION_ERROR
;
75 printf("code points:%ld len16:%ld len8:%ld "
77 (long)countInputCodePoints
, (long)bufferLen
, (long)utf8Length
,
78 (double)utf8Length
/countInputCodePoints
);
84 virtual UPerfFunction
* runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
= NULL
);
86 const UChar
*getBuffer() const { return buffer
; }
87 int32_t getBufferLen() const { return bufferLen
; }
92 // Number of code points in the input text.
93 int32_t countInputCodePoints
;
96 // Performance test function object.
97 class Command
: public UPerfFunction
{
99 Command(const UTrie2PerfTest
&testcase
) : testcase(testcase
) {}
102 virtual ~Command() {}
104 // virtual void call(UErrorCode* pErrorCode) { ... }
106 virtual long getOperationsPerIteration() {
107 // Number of code points tested.
108 return testcase
.countInputCodePoints
;
111 // virtual long getEventsPerIteration();
113 const UTrie2PerfTest
&testcase
;
114 UNormalizationCheckResult qcResult
;
117 class CheckFCD
: public Command
{
119 CheckFCD(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
121 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
122 return new CheckFCD(testcase
);
124 virtual void call(UErrorCode
* pErrorCode
) {
125 UErrorCode errorCode
=U_ZERO_ERROR
;
126 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
127 UNORM_FCD
, &errorCode
);
128 if(U_FAILURE(errorCode
)) {
129 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
130 u_errorName(errorCode
));
135 #if 0 // See comment at unorm_initUTrie2() forward declaration.
137 class CheckFCDAlwaysGet
: public Command
{
139 CheckFCDAlwaysGet(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
141 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
142 return new CheckFCDAlwaysGet(testcase
);
144 virtual void call(UErrorCode
* pErrorCode
) {
145 UErrorCode errorCode
=U_ZERO_ERROR
;
146 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
147 UNORM_FCD_ALWAYS_GET
, &errorCode
);
148 if(U_FAILURE(errorCode
)) {
149 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
150 u_errorName(errorCode
));
155 U_CAPI UBool U_EXPORT2
156 unorm_checkFCDUTF8(const uint8_t *src
, int32_t srcLength
, const UnicodeSet
*nx
);
158 class CheckFCDUTF8
: public Command
{
160 CheckFCDUTF8(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
162 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
163 return new CheckFCDUTF8(testcase
);
165 virtual void call(UErrorCode
* pErrorCode
) {
166 UBool isFCD
=unorm_checkFCDUTF8((const uint8_t *)testcase
.utf8
, testcase
.utf8Length
, NULL
);
168 fprintf(stderr
, "error: bogus result from unorm_checkFCDUTF8()\n");
175 class ToNFC
: public Command
{
177 ToNFC(const UTrie2PerfTest
&testcase
) : Command(testcase
) {
178 UErrorCode errorCode
=U_ZERO_ERROR
;
179 destCapacity
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
183 dest
=new UChar
[destCapacity
];
189 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
190 return new ToNFC(testcase
);
192 virtual void call(UErrorCode
* pErrorCode
) {
193 UErrorCode errorCode
=U_ZERO_ERROR
;
194 int32_t destLength
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
198 if(U_FAILURE(errorCode
) || destLength
!=destCapacity
) {
199 fprintf(stderr
, "error: unorm_normalize(UNORM_NFC) failed: %s\n",
200 u_errorName(errorCode
));
206 int32_t destCapacity
;
209 class GetBiDiClass
: public Command
{
211 GetBiDiClass(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
213 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
214 return new GetBiDiClass(testcase
);
216 virtual void call(UErrorCode
* pErrorCode
) {
217 const UChar
*buffer
=testcase
.getBuffer();
218 int32_t length
=testcase
.getBufferLen();
222 for(i
=0; i
<length
;) {
223 U16_NEXT(buffer
, i
, length
, c
);
224 bitSet
|=(uint32_t)1<<u_charDirection(c
);
226 if(length
>0 && bitSet
==0) {
227 fprintf(stderr
, "error: GetBiDiClass() did not collect bits\n");
232 UPerfFunction
* UTrie2PerfTest::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
) {
234 case 0: name
= "CheckFCD"; if (exec
) return CheckFCD::get(*this); break;
235 case 1: name
= "ToNFC"; if (exec
) return ToNFC::get(*this); break;
236 case 2: name
= "GetBiDiClass"; if (exec
) return GetBiDiClass::get(*this); break;
237 #if 0 // See comment at unorm_initUTrie2() forward declaration.
238 case 3: name
= "CheckFCDAlwaysGet"; if (exec
) return CheckFCDAlwaysGet::get(*this); break;
239 case 4: name
= "CheckFCDUTF8"; if (exec
) return CheckFCDUTF8::get(*this); break;
241 default: name
= ""; break;
246 int main(int argc
, const char *argv
[]) {
247 UErrorCode status
= U_ZERO_ERROR
;
248 UTrie2PerfTest
test(argc
, argv
, status
);
250 if (U_FAILURE(status
)){
251 printf("The error is %s\n", u_errorName(status
));
256 if (test
.run() == FALSE
){
257 fprintf(stderr
, "FAILED: Tests could not be run please check the "