12e5b6d6dSopenharmony_ci/* 22e5b6d6dSopenharmony_ci *********************************************************************** 32e5b6d6dSopenharmony_ci * © 2016 and later: Unicode, Inc. and others. 42e5b6d6dSopenharmony_ci * License & terms of use: http://www.unicode.org/copyright.html 52e5b6d6dSopenharmony_ci *********************************************************************** 62e5b6d6dSopenharmony_ci *********************************************************************** 72e5b6d6dSopenharmony_ci * Copyright (C) 2002-2014, International Business Machines 82e5b6d6dSopenharmony_ci * Corporation and others. All Rights Reserved. 92e5b6d6dSopenharmony_ci *********************************************************************** 102e5b6d6dSopenharmony_ci * file name: utrie2perf.cpp 112e5b6d6dSopenharmony_ci * encoding: UTF-8 122e5b6d6dSopenharmony_ci * tab size: 8 (not used) 132e5b6d6dSopenharmony_ci * indentation:4 142e5b6d6dSopenharmony_ci * 152e5b6d6dSopenharmony_ci * created on: 2008sep07 162e5b6d6dSopenharmony_ci * created by: Markus W. Scherer 172e5b6d6dSopenharmony_ci * 182e5b6d6dSopenharmony_ci * Performance test program for UTrie2. 192e5b6d6dSopenharmony_ci */ 202e5b6d6dSopenharmony_ci 212e5b6d6dSopenharmony_ci#include <stdio.h> 222e5b6d6dSopenharmony_ci#include <stdlib.h> 232e5b6d6dSopenharmony_ci#include "unicode/uchar.h" 242e5b6d6dSopenharmony_ci#include "unicode/unorm.h" 252e5b6d6dSopenharmony_ci#include "unicode/uperf.h" 262e5b6d6dSopenharmony_ci#include "uoptions.h" 272e5b6d6dSopenharmony_ci 282e5b6d6dSopenharmony_ci#if 0 292e5b6d6dSopenharmony_ci// Left over from when icu/branches/markus/utf8 could use both old UTrie 302e5b6d6dSopenharmony_ci// and new UTrie2, switched with #if in unorm.cpp and ubidi_props.c. 312e5b6d6dSopenharmony_ci// Comparative benchmarks were done in that branch on revision r24630 322e5b6d6dSopenharmony_ci// and earlier. 332e5b6d6dSopenharmony_ciU_CAPI void U_EXPORT2 342e5b6d6dSopenharmony_ciunorm_initUTrie2(UErrorCode *pErrorCode); 352e5b6d6dSopenharmony_ci 362e5b6d6dSopenharmony_ciU_CAPI void U_EXPORT2 372e5b6d6dSopenharmony_ciubidi_initUTrie2(UErrorCode *pErrorCode); 382e5b6d6dSopenharmony_ci#endif 392e5b6d6dSopenharmony_ci 402e5b6d6dSopenharmony_ciU_NAMESPACE_BEGIN 412e5b6d6dSopenharmony_ci 422e5b6d6dSopenharmony_ciclass UnicodeSet; 432e5b6d6dSopenharmony_ci 442e5b6d6dSopenharmony_ciU_NAMESPACE_END 452e5b6d6dSopenharmony_ci 462e5b6d6dSopenharmony_ci// Test object. 472e5b6d6dSopenharmony_ciclass UTrie2PerfTest : public UPerfTest { 482e5b6d6dSopenharmony_cipublic: 492e5b6d6dSopenharmony_ci UTrie2PerfTest(int32_t argc, const char *argv[], UErrorCode &status) 502e5b6d6dSopenharmony_ci : UPerfTest(argc, argv, NULL, 0, "", status), 512e5b6d6dSopenharmony_ci utf8(NULL), utf8Length(0), countInputCodePoints(0) { 522e5b6d6dSopenharmony_ci if (U_SUCCESS(status)) { 532e5b6d6dSopenharmony_ci#if 0 // See comment at unorm_initUTrie2() forward declaration. 542e5b6d6dSopenharmony_ci unorm_initUTrie2(&status); 552e5b6d6dSopenharmony_ci ubidi_initUTrie2(&status); 562e5b6d6dSopenharmony_ci#endif 572e5b6d6dSopenharmony_ci int32_t inputLength; 582e5b6d6dSopenharmony_ci UPerfTest::getBuffer(inputLength, status); 592e5b6d6dSopenharmony_ci if(U_SUCCESS(status) && inputLength>0) { 602e5b6d6dSopenharmony_ci countInputCodePoints = u_countChar32(buffer, bufferLen); 612e5b6d6dSopenharmony_ci 622e5b6d6dSopenharmony_ci // Preflight the UTF-8 length and allocate utf8. 632e5b6d6dSopenharmony_ci u_strToUTF8(NULL, 0, &utf8Length, buffer, bufferLen, &status); 642e5b6d6dSopenharmony_ci if(status==U_BUFFER_OVERFLOW_ERROR) { 652e5b6d6dSopenharmony_ci utf8=(char *)malloc(utf8Length); 662e5b6d6dSopenharmony_ci if(utf8!=NULL) { 672e5b6d6dSopenharmony_ci status=U_ZERO_ERROR; 682e5b6d6dSopenharmony_ci u_strToUTF8(utf8, utf8Length, NULL, buffer, bufferLen, &status); 692e5b6d6dSopenharmony_ci } else { 702e5b6d6dSopenharmony_ci status=U_MEMORY_ALLOCATION_ERROR; 712e5b6d6dSopenharmony_ci } 722e5b6d6dSopenharmony_ci } 732e5b6d6dSopenharmony_ci 742e5b6d6dSopenharmony_ci if(verbose) { 752e5b6d6dSopenharmony_ci printf("code points:%ld len16:%ld len8:%ld " 762e5b6d6dSopenharmony_ci "B/cp:%.3g\n", 772e5b6d6dSopenharmony_ci (long)countInputCodePoints, (long)bufferLen, (long)utf8Length, 782e5b6d6dSopenharmony_ci (double)utf8Length/countInputCodePoints); 792e5b6d6dSopenharmony_ci } 802e5b6d6dSopenharmony_ci } 812e5b6d6dSopenharmony_ci } 822e5b6d6dSopenharmony_ci } 832e5b6d6dSopenharmony_ci 842e5b6d6dSopenharmony_ci virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec, const char* &name, char* par = NULL); 852e5b6d6dSopenharmony_ci 862e5b6d6dSopenharmony_ci const UChar *getBuffer() const { return buffer; } 872e5b6d6dSopenharmony_ci int32_t getBufferLen() const { return bufferLen; } 882e5b6d6dSopenharmony_ci 892e5b6d6dSopenharmony_ci char *utf8; 902e5b6d6dSopenharmony_ci int32_t utf8Length; 912e5b6d6dSopenharmony_ci 922e5b6d6dSopenharmony_ci // Number of code points in the input text. 932e5b6d6dSopenharmony_ci int32_t countInputCodePoints; 942e5b6d6dSopenharmony_ci}; 952e5b6d6dSopenharmony_ci 962e5b6d6dSopenharmony_ci// Performance test function object. 972e5b6d6dSopenharmony_ciclass Command : public UPerfFunction { 982e5b6d6dSopenharmony_ciprotected: 992e5b6d6dSopenharmony_ci Command(const UTrie2PerfTest &testcase) : testcase(testcase) {} 1002e5b6d6dSopenharmony_ci 1012e5b6d6dSopenharmony_cipublic: 1022e5b6d6dSopenharmony_ci virtual ~Command() {} 1032e5b6d6dSopenharmony_ci 1042e5b6d6dSopenharmony_ci // virtual void call(UErrorCode* pErrorCode) { ... } 1052e5b6d6dSopenharmony_ci 1062e5b6d6dSopenharmony_ci virtual long getOperationsPerIteration() { 1072e5b6d6dSopenharmony_ci // Number of code points tested. 1082e5b6d6dSopenharmony_ci return testcase.countInputCodePoints; 1092e5b6d6dSopenharmony_ci } 1102e5b6d6dSopenharmony_ci 1112e5b6d6dSopenharmony_ci // virtual long getEventsPerIteration(); 1122e5b6d6dSopenharmony_ci 1132e5b6d6dSopenharmony_ci const UTrie2PerfTest &testcase; 1142e5b6d6dSopenharmony_ci UNormalizationCheckResult qcResult; 1152e5b6d6dSopenharmony_ci}; 1162e5b6d6dSopenharmony_ci 1172e5b6d6dSopenharmony_ciclass CheckFCD : public Command { 1182e5b6d6dSopenharmony_ciprotected: 1192e5b6d6dSopenharmony_ci CheckFCD(const UTrie2PerfTest &testcase) : Command(testcase) {} 1202e5b6d6dSopenharmony_cipublic: 1212e5b6d6dSopenharmony_ci static UPerfFunction* get(const UTrie2PerfTest &testcase) { 1222e5b6d6dSopenharmony_ci return new CheckFCD(testcase); 1232e5b6d6dSopenharmony_ci } 1242e5b6d6dSopenharmony_ci virtual void call(UErrorCode* pErrorCode) { 1252e5b6d6dSopenharmony_ci UErrorCode errorCode=U_ZERO_ERROR; 1262e5b6d6dSopenharmony_ci qcResult=unorm_quickCheck(testcase.getBuffer(), testcase.getBufferLen(), 1272e5b6d6dSopenharmony_ci UNORM_FCD, &errorCode); 1282e5b6d6dSopenharmony_ci if(U_FAILURE(errorCode)) { 1292e5b6d6dSopenharmony_ci fprintf(stderr, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n", 1302e5b6d6dSopenharmony_ci u_errorName(errorCode)); 1312e5b6d6dSopenharmony_ci } 1322e5b6d6dSopenharmony_ci } 1332e5b6d6dSopenharmony_ci}; 1342e5b6d6dSopenharmony_ci 1352e5b6d6dSopenharmony_ci#if 0 // See comment at unorm_initUTrie2() forward declaration. 1362e5b6d6dSopenharmony_ci 1372e5b6d6dSopenharmony_ciclass CheckFCDAlwaysGet : public Command { 1382e5b6d6dSopenharmony_ciprotected: 1392e5b6d6dSopenharmony_ci CheckFCDAlwaysGet(const UTrie2PerfTest &testcase) : Command(testcase) {} 1402e5b6d6dSopenharmony_cipublic: 1412e5b6d6dSopenharmony_ci static UPerfFunction* get(const UTrie2PerfTest &testcase) { 1422e5b6d6dSopenharmony_ci return new CheckFCDAlwaysGet(testcase); 1432e5b6d6dSopenharmony_ci } 1442e5b6d6dSopenharmony_ci virtual void call(UErrorCode* pErrorCode) { 1452e5b6d6dSopenharmony_ci UErrorCode errorCode=U_ZERO_ERROR; 1462e5b6d6dSopenharmony_ci qcResult=unorm_quickCheck(testcase.getBuffer(), testcase.getBufferLen(), 1472e5b6d6dSopenharmony_ci UNORM_FCD_ALWAYS_GET, &errorCode); 1482e5b6d6dSopenharmony_ci if(U_FAILURE(errorCode)) { 1492e5b6d6dSopenharmony_ci fprintf(stderr, "error: unorm_quickCheck(UNORM_FCD) failed: %s\n", 1502e5b6d6dSopenharmony_ci u_errorName(errorCode)); 1512e5b6d6dSopenharmony_ci } 1522e5b6d6dSopenharmony_ci } 1532e5b6d6dSopenharmony_ci}; 1542e5b6d6dSopenharmony_ci 1552e5b6d6dSopenharmony_ciU_CAPI UBool U_EXPORT2 1562e5b6d6dSopenharmony_ciunorm_checkFCDUTF8(const uint8_t *src, int32_t srcLength, const UnicodeSet *nx); 1572e5b6d6dSopenharmony_ci 1582e5b6d6dSopenharmony_ciclass CheckFCDUTF8 : public Command { 1592e5b6d6dSopenharmony_ciprotected: 1602e5b6d6dSopenharmony_ci CheckFCDUTF8(const UTrie2PerfTest &testcase) : Command(testcase) {} 1612e5b6d6dSopenharmony_cipublic: 1622e5b6d6dSopenharmony_ci static UPerfFunction* get(const UTrie2PerfTest &testcase) { 1632e5b6d6dSopenharmony_ci return new CheckFCDUTF8(testcase); 1642e5b6d6dSopenharmony_ci } 1652e5b6d6dSopenharmony_ci virtual void call(UErrorCode* pErrorCode) { 1662e5b6d6dSopenharmony_ci UBool isFCD=unorm_checkFCDUTF8((const uint8_t *)testcase.utf8, testcase.utf8Length, NULL); 1672e5b6d6dSopenharmony_ci if(isFCD>1) { 1682e5b6d6dSopenharmony_ci fprintf(stderr, "error: bogus result from unorm_checkFCDUTF8()\n"); 1692e5b6d6dSopenharmony_ci } 1702e5b6d6dSopenharmony_ci } 1712e5b6d6dSopenharmony_ci}; 1722e5b6d6dSopenharmony_ci 1732e5b6d6dSopenharmony_ci#endif 1742e5b6d6dSopenharmony_ci 1752e5b6d6dSopenharmony_ciclass ToNFC : public Command { 1762e5b6d6dSopenharmony_ciprotected: 1772e5b6d6dSopenharmony_ci ToNFC(const UTrie2PerfTest &testcase) : Command(testcase) { 1782e5b6d6dSopenharmony_ci UErrorCode errorCode=U_ZERO_ERROR; 1792e5b6d6dSopenharmony_ci destCapacity=unorm_normalize(testcase.getBuffer(), testcase.getBufferLen(), 1802e5b6d6dSopenharmony_ci UNORM_NFC, 0, 1812e5b6d6dSopenharmony_ci NULL, 0, 1822e5b6d6dSopenharmony_ci &errorCode); 1832e5b6d6dSopenharmony_ci dest=new UChar[destCapacity]; 1842e5b6d6dSopenharmony_ci } 1852e5b6d6dSopenharmony_ci ~ToNFC() { 1862e5b6d6dSopenharmony_ci delete [] dest; 1872e5b6d6dSopenharmony_ci } 1882e5b6d6dSopenharmony_cipublic: 1892e5b6d6dSopenharmony_ci static UPerfFunction* get(const UTrie2PerfTest &testcase) { 1902e5b6d6dSopenharmony_ci return new ToNFC(testcase); 1912e5b6d6dSopenharmony_ci } 1922e5b6d6dSopenharmony_ci virtual void call(UErrorCode* pErrorCode) { 1932e5b6d6dSopenharmony_ci UErrorCode errorCode=U_ZERO_ERROR; 1942e5b6d6dSopenharmony_ci int32_t destLength=unorm_normalize(testcase.getBuffer(), testcase.getBufferLen(), 1952e5b6d6dSopenharmony_ci UNORM_NFC, 0, 1962e5b6d6dSopenharmony_ci dest, destCapacity, 1972e5b6d6dSopenharmony_ci &errorCode); 1982e5b6d6dSopenharmony_ci if(U_FAILURE(errorCode) || destLength!=destCapacity) { 1992e5b6d6dSopenharmony_ci fprintf(stderr, "error: unorm_normalize(UNORM_NFC) failed: %s\n", 2002e5b6d6dSopenharmony_ci u_errorName(errorCode)); 2012e5b6d6dSopenharmony_ci } 2022e5b6d6dSopenharmony_ci } 2032e5b6d6dSopenharmony_ci 2042e5b6d6dSopenharmony_ciprivate: 2052e5b6d6dSopenharmony_ci UChar *dest; 2062e5b6d6dSopenharmony_ci int32_t destCapacity; 2072e5b6d6dSopenharmony_ci}; 2082e5b6d6dSopenharmony_ci 2092e5b6d6dSopenharmony_ciclass GetBiDiClass : public Command { 2102e5b6d6dSopenharmony_ciprotected: 2112e5b6d6dSopenharmony_ci GetBiDiClass(const UTrie2PerfTest &testcase) : Command(testcase) {} 2122e5b6d6dSopenharmony_cipublic: 2132e5b6d6dSopenharmony_ci static UPerfFunction* get(const UTrie2PerfTest &testcase) { 2142e5b6d6dSopenharmony_ci return new GetBiDiClass(testcase); 2152e5b6d6dSopenharmony_ci } 2162e5b6d6dSopenharmony_ci virtual void call(UErrorCode* pErrorCode) { 2172e5b6d6dSopenharmony_ci const UChar *buffer=testcase.getBuffer(); 2182e5b6d6dSopenharmony_ci int32_t length=testcase.getBufferLen(); 2192e5b6d6dSopenharmony_ci UChar32 c; 2202e5b6d6dSopenharmony_ci int32_t i; 2212e5b6d6dSopenharmony_ci uint32_t bitSet=0; 2222e5b6d6dSopenharmony_ci for(i=0; i<length;) { 2232e5b6d6dSopenharmony_ci U16_NEXT(buffer, i, length, c); 2242e5b6d6dSopenharmony_ci bitSet|=(uint32_t)1<<u_charDirection(c); 2252e5b6d6dSopenharmony_ci } 2262e5b6d6dSopenharmony_ci if(length>0 && bitSet==0) { 2272e5b6d6dSopenharmony_ci fprintf(stderr, "error: GetBiDiClass() did not collect bits\n"); 2282e5b6d6dSopenharmony_ci } 2292e5b6d6dSopenharmony_ci } 2302e5b6d6dSopenharmony_ci}; 2312e5b6d6dSopenharmony_ci 2322e5b6d6dSopenharmony_ciUPerfFunction* UTrie2PerfTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* par) { 2332e5b6d6dSopenharmony_ci switch (index) { 2342e5b6d6dSopenharmony_ci case 0: name = "CheckFCD"; if (exec) return CheckFCD::get(*this); break; 2352e5b6d6dSopenharmony_ci case 1: name = "ToNFC"; if (exec) return ToNFC::get(*this); break; 2362e5b6d6dSopenharmony_ci case 2: name = "GetBiDiClass"; if (exec) return GetBiDiClass::get(*this); break; 2372e5b6d6dSopenharmony_ci#if 0 // See comment at unorm_initUTrie2() forward declaration. 2382e5b6d6dSopenharmony_ci case 3: name = "CheckFCDAlwaysGet"; if (exec) return CheckFCDAlwaysGet::get(*this); break; 2392e5b6d6dSopenharmony_ci case 4: name = "CheckFCDUTF8"; if (exec) return CheckFCDUTF8::get(*this); break; 2402e5b6d6dSopenharmony_ci#endif 2412e5b6d6dSopenharmony_ci default: name = ""; break; 2422e5b6d6dSopenharmony_ci } 2432e5b6d6dSopenharmony_ci return NULL; 2442e5b6d6dSopenharmony_ci} 2452e5b6d6dSopenharmony_ci 2462e5b6d6dSopenharmony_ciint main(int argc, const char *argv[]) { 2472e5b6d6dSopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2482e5b6d6dSopenharmony_ci UTrie2PerfTest test(argc, argv, status); 2492e5b6d6dSopenharmony_ci 2502e5b6d6dSopenharmony_ci if (U_FAILURE(status)){ 2512e5b6d6dSopenharmony_ci printf("The error is %s\n", u_errorName(status)); 2522e5b6d6dSopenharmony_ci test.usage(); 2532e5b6d6dSopenharmony_ci return status; 2542e5b6d6dSopenharmony_ci } 2552e5b6d6dSopenharmony_ci 2562e5b6d6dSopenharmony_ci if (test.run() == false){ 2572e5b6d6dSopenharmony_ci fprintf(stderr, "FAILED: Tests could not be run please check the " 2582e5b6d6dSopenharmony_ci "arguments.\n"); 2592e5b6d6dSopenharmony_ci return -1; 2602e5b6d6dSopenharmony_ci } 2612e5b6d6dSopenharmony_ci 2622e5b6d6dSopenharmony_ci return 0; 2632e5b6d6dSopenharmony_ci} 264