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