Home | History | Annotate | Download | only in utrie2perf
      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)utf8Length,
     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.getBufferLen(),
    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 char* &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(*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;
    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 }
    260