2 **********************************************************************
3 * Copyright (C) 2002-2008, 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"
24 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
27 // Left over from when icu/branches/markus/utf8 could use both old UTrie
28 // and new UTrie2, switched with #if in unorm.cpp and ubidi_props.c.
29 // Comparative benchmarks were done in that branch on revision r24630
32 unorm_initUTrie2(UErrorCode
*pErrorCode
);
35 ubidi_initUTrie2(UErrorCode
*pErrorCode
);
45 class UTrie2PerfTest
: public UPerfTest
{
47 UTrie2PerfTest(int32_t argc
, const char *argv
[], UErrorCode
&status
)
48 : UPerfTest(argc
, argv
, NULL
, 0, "", status
),
49 utf8(NULL
), utf8Length(0), countInputCodePoints(0) {
50 if (U_SUCCESS(status
)) {
51 #if 0 // See comment at unorm_initUTrie2() forward declaration.
52 unorm_initUTrie2(&status
);
53 ubidi_initUTrie2(&status
);
56 UPerfTest::getBuffer(inputLength
, status
);
57 if(U_SUCCESS(status
) && inputLength
>0) {
58 countInputCodePoints
= u_countChar32(buffer
, bufferLen
);
60 // Preflight the UTF-8 length and allocate utf8.
61 u_strToUTF8(NULL
, 0, &utf8Length
, buffer
, bufferLen
, &status
);
62 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
63 utf8
=(char *)malloc(utf8Length
);
66 u_strToUTF8(utf8
, utf8Length
, NULL
, buffer
, bufferLen
, &status
);
68 status
=U_MEMORY_ALLOCATION_ERROR
;
73 printf("code points:%ld len16:%ld len8:%ld "
75 (long)countInputCodePoints
, (long)bufferLen
, (long)utf8Length
,
76 (double)utf8Length
/countInputCodePoints
);
82 virtual UPerfFunction
* runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
= NULL
);
84 const UChar
*getBuffer() const { return buffer
; }
85 int32_t getBufferLen() const { return bufferLen
; }
90 // Number of code points in the input text.
91 int32_t countInputCodePoints
;
94 // Performance test function object.
95 class Command
: public UPerfFunction
{
97 Command(const UTrie2PerfTest
&testcase
) : testcase(testcase
) {}
100 virtual ~Command() {}
102 // virtual void call(UErrorCode* pErrorCode) { ... }
104 virtual long getOperationsPerIteration() {
105 // Number of code points tested.
106 return testcase
.countInputCodePoints
;
109 // virtual long getEventsPerIteration();
111 const UTrie2PerfTest
&testcase
;
112 UNormalizationCheckResult qcResult
;
115 class CheckFCD
: public Command
{
117 CheckFCD(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
119 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
120 return new CheckFCD(testcase
);
122 virtual void call(UErrorCode
* pErrorCode
) {
123 UErrorCode errorCode
=U_ZERO_ERROR
;
124 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
125 UNORM_FCD
, &errorCode
);
126 if(U_FAILURE(errorCode
)) {
127 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
128 u_errorName(errorCode
));
133 #if 0 // See comment at unorm_initUTrie2() forward declaration.
135 class CheckFCDAlwaysGet
: public Command
{
137 CheckFCDAlwaysGet(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
139 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
140 return new CheckFCDAlwaysGet(testcase
);
142 virtual void call(UErrorCode
* pErrorCode
) {
143 UErrorCode errorCode
=U_ZERO_ERROR
;
144 qcResult
=unorm_quickCheck(testcase
.getBuffer(), testcase
.getBufferLen(),
145 UNORM_FCD_ALWAYS_GET
, &errorCode
);
146 if(U_FAILURE(errorCode
)) {
147 fprintf(stderr
, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n",
148 u_errorName(errorCode
));
153 U_CAPI UBool U_EXPORT2
154 unorm_checkFCDUTF8(const uint8_t *src
, int32_t srcLength
, const UnicodeSet
*nx
);
156 class CheckFCDUTF8
: public Command
{
158 CheckFCDUTF8(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
160 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
161 return new CheckFCDUTF8(testcase
);
163 virtual void call(UErrorCode
* pErrorCode
) {
164 UBool isFCD
=unorm_checkFCDUTF8((const uint8_t *)testcase
.utf8
, testcase
.utf8Length
, NULL
);
166 fprintf(stderr
, "error: bogus result from unorm_checkFCDUTF8()\n");
173 class ToNFC
: public Command
{
175 ToNFC(const UTrie2PerfTest
&testcase
) : Command(testcase
) {
176 UErrorCode errorCode
=U_ZERO_ERROR
;
177 destCapacity
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
181 dest
=new UChar
[destCapacity
];
187 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
188 return new ToNFC(testcase
);
190 virtual void call(UErrorCode
* pErrorCode
) {
191 UErrorCode errorCode
=U_ZERO_ERROR
;
192 int32_t destLength
=unorm_normalize(testcase
.getBuffer(), testcase
.getBufferLen(),
196 if(U_FAILURE(errorCode
) || destLength
!=destCapacity
) {
197 fprintf(stderr
, "error: unorm_normalize(UNORM_NFC) failed: %s\n",
198 u_errorName(errorCode
));
204 int32_t destCapacity
;
207 class GetBiDiClass
: public Command
{
209 GetBiDiClass(const UTrie2PerfTest
&testcase
) : Command(testcase
) {}
211 static UPerfFunction
* get(const UTrie2PerfTest
&testcase
) {
212 return new GetBiDiClass(testcase
);
214 virtual void call(UErrorCode
* pErrorCode
) {
215 const UChar
*buffer
=testcase
.getBuffer();
216 int32_t length
=testcase
.getBufferLen();
220 for(i
=0; i
<length
;) {
221 U16_NEXT(buffer
, i
, length
, c
);
222 bitSet
|=(uint32_t)1<<u_charDirection(c
);
224 if(length
>0 && bitSet
==0) {
225 fprintf(stderr
, "error: GetBiDiClass() did not collect bits\n");
230 UPerfFunction
* UTrie2PerfTest::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* par
) {
232 case 0: name
= "CheckFCD"; if (exec
) return CheckFCD::get(*this); break;
233 case 1: name
= "ToNFC"; if (exec
) return ToNFC::get(*this); break;
234 case 2: name
= "GetBiDiClass"; if (exec
) return GetBiDiClass::get(*this); break;
235 #if 0 // See comment at unorm_initUTrie2() forward declaration.
236 case 3: name
= "CheckFCDAlwaysGet"; if (exec
) return CheckFCDAlwaysGet::get(*this); break;
237 case 4: name
= "CheckFCDUTF8"; if (exec
) return CheckFCDUTF8::get(*this); break;
239 default: name
= ""; break;
244 int main(int argc
, const char *argv
[]) {
245 UErrorCode status
= U_ZERO_ERROR
;
246 UTrie2PerfTest
test(argc
, argv
, status
);
248 if (U_FAILURE(status
)){
249 printf("The error is %s\n", u_errorName(status
));
254 if (test
.run() == FALSE
){
255 fprintf(stderr
, "FAILED: Tests could not be run please check the "