2 **********************************************************************
3 * Copyright (C) 2002-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 * file name: utrie2perf.cpp
8 * tab size: 8 (not used)
11 * created on: 2008sep07
12 * created by: Markus W. Scherer
14 * Performance test program for UTrie2.
19 #include "unicode/uchar.h"
20 #include "unicode/unorm.h"
21 #include "unicode/uperf.h"
25 // Left over from when icu/branches/markus/utf8 could use both old UTrie
26 // and new UTrie2, switched with #if in unorm.cpp and ubidi_props.c.
27 // Comparative benchmarks were done in that branch on revision r24630
30 unorm_initUTrie2(UErrorCode
*pErrorCode
);
33 ubidi_initUTrie2(UErrorCode
*pErrorCode
);
43 class UTrie2PerfTest
: public UPerfTest
{
45 UTrie2PerfTest(int32_t argc
, const char *argv
[], UErrorCode
&status
)
46 : UPerfTest(argc
, argv
, NULL
, 0, "", status
),
47 utf8(NULL
), utf8Length(0), countInputCodePoints(0) {
48 if (U_SUCCESS(status
)) {
49 #if 0 // See comment at unorm_initUTrie2() forward declaration.
50 unorm_initUTrie2(&status
);
51 ubidi_initUTrie2(&status
);
54 UPerfTest::getBuffer(inputLength
, status
);
55 if(U_SUCCESS(status
) && inputLength
>0) {
56 countInputCodePoints
= u_countChar32(buffer
, bufferLen
);
58 // Preflight the UTF-8 length and allocate utf8.
59 u_strToUTF8(NULL
, 0, &utf8Length
, buffer
, bufferLen
, &status
);
60 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
61 utf8
=(char *)malloc(utf8Length
);
64 u_strToUTF8(utf8
, utf8Length
, NULL
, buffer
, bufferLen
, &status
);
66 status
=U_MEMORY_ALLOCATION_ERROR
;
71 printf("code points:%ld len16:%ld len8:%ld "
73 (long)countInputCodePoints
, (long)bufferLen
, (long)utf8Length
,
74 (double)utf8Length
/countInputCodePoints
);
80 virtual UPerfFunction
* runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
= NULL
);
82 const UChar
*getBuffer() const { return buffer
; }
83 int32_t getBufferLen() const { return bufferLen
; }
88 // Number of code points in the input text.
89 int32_t countInputCodePoints
;
92 // Performance test function object.
93 class Command
: public UPerfFunction
{
95 Command(const UTrie2PerfTest
&testcase
) : testcase(testcase
) {}
100 // virtual void call(UErrorCode* pErrorCode) { ... }
102 virtual long getOperationsPerIteration() {
103 // Number of code points tested.
104 return testcase
.countInputCodePoints
;
107 // virtual long getEventsPerIteration();
109 const UTrie2PerfTest
&testcase
;
110 UNormalizationCheckResult qcResult
;
113 class CheckFCD
: public Command
{
115 CheckFCD(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
117 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
118 return new CheckFCD(testcase
);
120 virtual void call(UErrorCode
* pErrorCode
) {
121 UErrorCode errorCode
=U_ZERO_ERROR
;
122 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
123 UNORM_FCD
, &errorCode
);
124 if(U_FAILURE(errorCode
)) {
125 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
126 u_errorName(errorCode
));
131 #if 0 // See comment at unorm_initUTrie2() forward declaration.
133 class CheckFCDAlwaysGet
: public Command
{
135 CheckFCDAlwaysGet(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
137 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
138 return new CheckFCDAlwaysGet(testcase
);
140 virtual void call(UErrorCode
* pErrorCode
) {
141 UErrorCode errorCode
=U_ZERO_ERROR
;
142 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
143 UNORM_FCD_ALWAYS_GET
, &errorCode
);
144 if(U_FAILURE(errorCode
)) {
145 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
146 u_errorName(errorCode
));
151 U_CAPI UBool U_EXPORT2
152 unorm_checkFCDUTF8(const uint8_t *src
, int32_t srcLength
, const UnicodeSet
*nx
);
154 class CheckFCDUTF8
: public Command
{
156 CheckFCDUTF8(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
158 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
159 return new CheckFCDUTF8(testcase
);
161 virtual void call(UErrorCode
* pErrorCode
) {
162 UBool isFCD
=unorm_checkFCDUTF8((const uint8_t *)testcase
.utf8
, testcase
.utf8Length
, NULL
);
164 fprintf(stderr
, "error: bogus result from unorm_checkFCDUTF8()\n");
171 class ToNFC
: public Command
{
173 ToNFC(const UTrie2PerfTest
&testcase
) : Command(testcase
) {
174 UErrorCode errorCode
=U_ZERO_ERROR
;
175 destCapacity
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
179 dest
=new UChar
[destCapacity
];
185 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
186 return new ToNFC(testcase
);
188 virtual void call(UErrorCode
* pErrorCode
) {
189 UErrorCode errorCode
=U_ZERO_ERROR
;
190 int32_t destLength
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
194 if(U_FAILURE(errorCode
) || destLength
!=destCapacity
) {
195 fprintf(stderr
, "error: unorm_normalize(UNORM_NFC) failed: %s\n",
196 u_errorName(errorCode
));
202 int32_t destCapacity
;
205 class GetBiDiClass
: public Command
{
207 GetBiDiClass(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
209 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
210 return new GetBiDiClass(testcase
);
212 virtual void call(UErrorCode
* pErrorCode
) {
213 const UChar
*buffer
=testcase
.getBuffer();
214 int32_t length
=testcase
.getBufferLen();
218 for(i
=0; i
<length
;) {
219 U16_NEXT(buffer
, i
, length
, c
);
220 bitSet
|=(uint32_t)1<<u_charDirection(c
);
222 if(length
>0 && bitSet
==0) {
223 fprintf(stderr
, "error: GetBiDiClass() did not collect bits\n");
228 UPerfFunction
* UTrie2PerfTest::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
) {
230 case 0: name
= "CheckFCD"; if (exec
) return CheckFCD::get(*this); break;
231 case 1: name
= "ToNFC"; if (exec
) return ToNFC::get(*this); break;
232 case 2: name
= "GetBiDiClass"; if (exec
) return GetBiDiClass::get(*this); break;
233 #if 0 // See comment at unorm_initUTrie2() forward declaration.
234 case 3: name
= "CheckFCDAlwaysGet"; if (exec
) return CheckFCDAlwaysGet::get(*this); break;
235 case 4: name
= "CheckFCDUTF8"; if (exec
) return CheckFCDUTF8::get(*this); break;
237 default: name
= ""; break;
242 int main(int argc
, const char *argv
[]) {
243 UErrorCode status
= U_ZERO_ERROR
;
244 UTrie2PerfTest
test(argc
, argv
, status
);
246 if (U_FAILURE(status
)){
247 printf("The error is %s\n", u_errorName(status
));
252 if (test
.run() == FALSE
){
253 fprintf(stderr
, "FAILED: Tests could not be run please check the "