OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ********************************************************************** |
| 3 * Copyright (C) 2002-2008, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. |
| 5 ********************************************************************** |
| 6 * file name: utrie2perf.cpp |
| 7 * encoding: US-ASCII |
| 8 * tab size: 8 (not used) |
| 9 * indentation:4 |
| 10 * |
| 11 * created on: 2008sep07 |
| 12 * created by: Markus W. Scherer |
| 13 * |
| 14 * Performance test program for UTrie2. |
| 15 */ |
| 16 |
| 17 #include <stdio.h> |
| 18 #include <stdlib.h> |
| 19 #include "unicode/uchar.h" |
| 20 #include "unicode/unorm.h" |
| 21 #include "unicode/uperf.h" |
| 22 #include "uoptions.h" |
| 23 |
| 24 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) |
| 25 |
| 26 #if 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 |
| 30 // and earlier. |
| 31 U_CAPI void U_EXPORT2 |
| 32 unorm_initUTrie2(UErrorCode *pErrorCode); |
| 33 |
| 34 U_CAPI void U_EXPORT2 |
| 35 ubidi_initUTrie2(UErrorCode *pErrorCode); |
| 36 #endif |
| 37 |
| 38 U_NAMESPACE_BEGIN |
| 39 |
| 40 class UnicodeSet; |
| 41 |
| 42 U_NAMESPACE_END |
| 43 |
| 44 // Test object. |
| 45 class UTrie2PerfTest : public UPerfTest { |
| 46 public: |
| 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); |
| 54 #endif |
| 55 int32_t inputLength; |
| 56 UPerfTest::getBuffer(inputLength, status); |
| 57 if(U_SUCCESS(status) && inputLength>0) { |
| 58 countInputCodePoints = u_countChar32(buffer, bufferLen); |
| 59 |
| 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); |
| 64 if(utf8!=NULL) { |
| 65 status=U_ZERO_ERROR; |
| 66 u_strToUTF8(utf8, utf8Length, NULL, buffer, bufferLen, &
status); |
| 67 } else { |
| 68 status=U_MEMORY_ALLOCATION_ERROR; |
| 69 } |
| 70 } |
| 71 |
| 72 if(verbose) { |
| 73 printf("code points:%ld len16:%ld len8:%ld " |
| 74 "B/cp:%.3g\n", |
| 75 (long)countInputCodePoints, (long)bufferLen, (long)ut
f8Length, |
| 76 (double)utf8Length/countInputCodePoints); |
| 77 } |
| 78 } |
| 79 } |
| 80 } |
| 81 |
| 82 virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec, const char*
&name, char* par = NULL); |
| 83 |
| 84 const UChar *getBuffer() const { return buffer; } |
| 85 int32_t getBufferLen() const { return bufferLen; } |
| 86 |
| 87 char *utf8; |
| 88 int32_t utf8Length; |
| 89 |
| 90 // Number of code points in the input text. |
| 91 int32_t countInputCodePoints; |
| 92 }; |
| 93 |
| 94 // Performance test function object. |
| 95 class Command : public UPerfFunction { |
| 96 protected: |
| 97 Command(const UTrie2PerfTest &testcase) : testcase(testcase) {} |
| 98 |
| 99 public: |
| 100 virtual ~Command() {} |
| 101 |
| 102 // virtual void call(UErrorCode* pErrorCode) { ... } |
| 103 |
| 104 virtual long getOperationsPerIteration() { |
| 105 // Number of code points tested. |
| 106 return testcase.countInputCodePoints; |
| 107 } |
| 108 |
| 109 // virtual long getEventsPerIteration(); |
| 110 |
| 111 const UTrie2PerfTest &testcase; |
| 112 UNormalizationCheckResult qcResult; |
| 113 }; |
| 114 |
| 115 class CheckFCD : public Command { |
| 116 protected: |
| 117 CheckFCD(const UTrie2PerfTest &testcase) : Command(testcase) {} |
| 118 public: |
| 119 static UPerfFunction* get(const UTrie2PerfTest &testcase) { |
| 120 return new CheckFCD(testcase); |
| 121 } |
| 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)); |
| 129 } |
| 130 } |
| 131 }; |
| 132 |
| 133 #if 0 // See comment at unorm_initUTrie2() forward declaration. |
| 134 |
| 135 class CheckFCDAlwaysGet : public Command { |
| 136 protected: |
| 137 CheckFCDAlwaysGet(const UTrie2PerfTest &testcase) : Command(testcase) {} |
| 138 public: |
| 139 static UPerfFunction* get(const UTrie2PerfTest &testcase) { |
| 140 return new CheckFCDAlwaysGet(testcase); |
| 141 } |
| 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)); |
| 149 } |
| 150 } |
| 151 }; |
| 152 |
| 153 U_CAPI UBool U_EXPORT2 |
| 154 unorm_checkFCDUTF8(const uint8_t *src, int32_t srcLength, const UnicodeSet *nx); |
| 155 |
| 156 class CheckFCDUTF8 : public Command { |
| 157 protected: |
| 158 CheckFCDUTF8(const UTrie2PerfTest &testcase) : Command(testcase) {} |
| 159 public: |
| 160 static UPerfFunction* get(const UTrie2PerfTest &testcase) { |
| 161 return new CheckFCDUTF8(testcase); |
| 162 } |
| 163 virtual void call(UErrorCode* pErrorCode) { |
| 164 UBool isFCD=unorm_checkFCDUTF8((const uint8_t *)testcase.utf8, testcase.
utf8Length, NULL); |
| 165 if(isFCD>1) { |
| 166 fprintf(stderr, "error: bogus result from unorm_checkFCDUTF8()\n"); |
| 167 } |
| 168 } |
| 169 }; |
| 170 |
| 171 #endif |
| 172 |
| 173 class ToNFC : public Command { |
| 174 protected: |
| 175 ToNFC(const UTrie2PerfTest &testcase) : Command(testcase) { |
| 176 UErrorCode errorCode=U_ZERO_ERROR; |
| 177 destCapacity=unorm_normalize(testcase.getBuffer(), testcase.getBufferLen
(), |
| 178 UNORM_NFC, 0, |
| 179 NULL, 0, |
| 180 &errorCode); |
| 181 dest=new UChar[destCapacity]; |
| 182 } |
| 183 ~ToNFC() { |
| 184 delete [] dest; |
| 185 } |
| 186 public: |
| 187 static UPerfFunction* get(const UTrie2PerfTest &testcase) { |
| 188 return new ToNFC(testcase); |
| 189 } |
| 190 virtual void call(UErrorCode* pErrorCode) { |
| 191 UErrorCode errorCode=U_ZERO_ERROR; |
| 192 int32_t destLength=unorm_normalize(testcase.getBuffer(), testcase.getBuf
ferLen(), |
| 193 UNORM_NFC, 0, |
| 194 dest, destCapacity, |
| 195 &errorCode); |
| 196 if(U_FAILURE(errorCode) || destLength!=destCapacity) { |
| 197 fprintf(stderr, "error: unorm_normalize(UNORM_NFC) failed: %s\n", |
| 198 u_errorName(errorCode)); |
| 199 } |
| 200 } |
| 201 |
| 202 private: |
| 203 UChar *dest; |
| 204 int32_t destCapacity; |
| 205 }; |
| 206 |
| 207 class GetBiDiClass : public Command { |
| 208 protected: |
| 209 GetBiDiClass(const UTrie2PerfTest &testcase) : Command(testcase) {} |
| 210 public: |
| 211 static UPerfFunction* get(const UTrie2PerfTest &testcase) { |
| 212 return new GetBiDiClass(testcase); |
| 213 } |
| 214 virtual void call(UErrorCode* pErrorCode) { |
| 215 const UChar *buffer=testcase.getBuffer(); |
| 216 int32_t length=testcase.getBufferLen(); |
| 217 UChar32 c; |
| 218 int32_t i; |
| 219 uint32_t bitSet=0; |
| 220 for(i=0; i<length;) { |
| 221 U16_NEXT(buffer, i, length, c); |
| 222 bitSet|=(uint32_t)1<<u_charDirection(c); |
| 223 } |
| 224 if(length>0 && bitSet==0) { |
| 225 fprintf(stderr, "error: GetBiDiClass() did not collect bits\n"); |
| 226 } |
| 227 } |
| 228 }; |
| 229 |
| 230 UPerfFunction* UTrie2PerfTest::runIndexedTest(int32_t index, UBool exec, const c
har* &name, char* par) { |
| 231 switch (index) { |
| 232 case 0: name = "CheckFCD"; if (exec) return CheckFCD::get(*
this); break; |
| 233 case 1: name = "ToNFC"; if (exec) return ToNFC::get(*thi
s); break; |
| 234 case 2: name = "GetBiDiClass"; if (exec) return GetBiDiClass::g
et(*this); break; |
| 235 #if 0 // See comment at unorm_initUTrie2() forward declaration. |
| 236 case 3: name = "CheckFCDAlwaysGet"; if (exec) return CheckFCDAlwaysG
et::get(*this); break; |
| 237 case 4: name = "CheckFCDUTF8"; if (exec) return CheckFCDUTF8::g
et(*this); break; |
| 238 #endif |
| 239 default: name = ""; break; |
| 240 } |
| 241 return NULL; |
| 242 } |
| 243 |
| 244 int main(int argc, const char *argv[]) { |
| 245 UErrorCode status = U_ZERO_ERROR; |
| 246 UTrie2PerfTest test(argc, argv, status); |
| 247 |
| 248 if (U_FAILURE(status)){ |
| 249 printf("The error is %s\n", u_errorName(status)); |
| 250 test.usage(); |
| 251 return status; |
| 252 } |
| 253 |
| 254 if (test.run() == FALSE){ |
| 255 fprintf(stderr, "FAILED: Tests could not be run please check the " |
| 256 "arguments.\n"); |
| 257 return -1; |
| 258 } |
| 259 |
| 260 return 0; |
| 261 } |
OLD | NEW |