| 1 | // © 2016 and later: Unicode, Inc. and others. |
| 2 | // License & terms of use: http://www.unicode.org/copyright.html |
| 3 | /* |
| 4 | ********************************************************************** |
| 5 | * Copyright (c) 2002-2014, International Business Machines |
| 6 | * Corporation and others. All Rights Reserved. |
| 7 | ********************************************************************** |
| 8 | */ |
| 9 | #ifndef _UPERF_H |
| 10 | #define _UPERF_H |
| 11 | |
| 12 | #include "unicode/utypes.h" |
| 13 | #include "unicode/unistr.h" |
| 14 | #include "unicode/ustring.h" |
| 15 | |
| 16 | #include "unicode/testtype.h" |
| 17 | #include "unicode/utimer.h" |
| 18 | #include "ucbuf.h" |
| 19 | |
| 20 | // Forward declarations from uoptions.h. |
| 21 | struct UOption; |
| 22 | typedef struct UOption UOption; |
| 23 | |
| 24 | #if !UCONFIG_NO_CONVERSION |
| 25 | |
| 26 | U_NAMESPACE_USE |
| 27 | // Use the TESTCASE macro in subclasses of UPerfTest. Define the |
| 28 | // runIndexedTest method in this fashion: |
| 29 | // |
| 30 | //| void MyTest::runIndexedTest(int32_t index, UBool exec, |
| 31 | //| const char* &name, char* /*par*/) { |
| 32 | //| switch (index) { |
| 33 | //| TESTCASE(0,TestSomething); |
| 34 | //| TESTCASE(1,TestSomethingElse); |
| 35 | //| TESTCASE(2,TestAnotherThing); |
| 36 | //| default: |
| 37 | //| name = ""; |
| 38 | //| break; |
| 39 | //| } |
| 40 | //| return NULL; |
| 41 | //| } |
| 42 | #define TESTCASE(id,test) \ |
| 43 | case id: \ |
| 44 | name = #test; \ |
| 45 | if (exec) { \ |
| 46 | return test(); \ |
| 47 | } \ |
| 48 | break |
| 49 | |
| 50 | // More convenient macros. These allow easy reordering of the test cases. |
| 51 | // Copied from intltest.h, and adjusted to not logln() but return a UPerfFunction. |
| 52 | // |
| 53 | //| void MyTest::runIndexedTest(int32_t index, UBool exec, |
| 54 | //| const char* &name, char* /*par*/) { |
| 55 | //| TESTCASE_AUTO_BEGIN; |
| 56 | //| TESTCASE_AUTO(TestSomething); |
| 57 | //| TESTCASE_AUTO(TestSomethingElse); |
| 58 | //| TESTCASE_AUTO(TestAnotherThing); |
| 59 | //| TESTCASE_AUTO_END; |
| 60 | //| return NULL; |
| 61 | //| } |
| 62 | #define TESTCASE_AUTO_BEGIN \ |
| 63 | for(;;) { \ |
| 64 | int32_t testCaseAutoNumber = 0 |
| 65 | |
| 66 | #define TESTCASE_AUTO(test) \ |
| 67 | if (index == testCaseAutoNumber++) { \ |
| 68 | name = #test; \ |
| 69 | if (exec) { \ |
| 70 | return test(); \ |
| 71 | } \ |
| 72 | break; \ |
| 73 | } |
| 74 | |
| 75 | #define TESTCASE_AUTO_END \ |
| 76 | name = ""; \ |
| 77 | break; \ |
| 78 | } |
| 79 | |
| 80 | /** |
| 81 | * Subclasses of PerfTest will need to create subclasses of |
| 82 | * Function that define a call() method which contains the code to |
| 83 | * be timed. They then call setTestFunction() in their "Test..." |
| 84 | * method to establish this as the current test functor. |
| 85 | */ |
| 86 | class T_CTEST_EXPORT_API UPerfFunction { |
| 87 | public: |
| 88 | /** |
| 89 | * destructor |
| 90 | */ |
| 91 | virtual ~UPerfFunction(); |
| 92 | |
| 93 | /** |
| 94 | * Subclasses must implement this method to do the action to be |
| 95 | * measured. |
| 96 | */ |
| 97 | virtual void call(UErrorCode* status)=0; |
| 98 | |
| 99 | /** |
| 100 | * Subclasses must implement this method to return positive |
| 101 | * integer indicating the number of operations in a single |
| 102 | * call to this object's call() method. |
| 103 | */ |
| 104 | virtual long getOperationsPerIteration()=0; |
| 105 | /** |
| 106 | * Subclasses should override this method to return either positive |
| 107 | * or negative integer indicating the number of events in a single |
| 108 | * call to this object's call() method, if applicable |
| 109 | * e.g: Number of breaks / iterations for break iterator |
| 110 | */ |
| 111 | virtual long getEventsPerIteration(){ |
| 112 | return -1; |
| 113 | } |
| 114 | /** |
| 115 | * Call call() n times in a tight loop and return the elapsed |
| 116 | * milliseconds. If n is small and call() is fast the return |
| 117 | * result may be zero. Small return values have limited |
| 118 | * meaningfulness, depending on the underlying CPU and OS. |
| 119 | */ |
| 120 | virtual double time(int32_t n, UErrorCode* status) { |
| 121 | UTimer start, stop; |
| 122 | utimer_getTime(&start); |
| 123 | while (n-- > 0) { |
| 124 | call(status); |
| 125 | } |
| 126 | utimer_getTime(&stop); |
| 127 | return utimer_getDeltaSeconds(&start,&stop); // ms |
| 128 | } |
| 129 | |
| 130 | }; |
| 131 | |
| 132 | |
| 133 | class T_CTEST_EXPORT_API UPerfTest { |
| 134 | public: |
| 135 | UBool run(); |
| 136 | UBool runTest( char* name = NULL, char* par = NULL ); // not to be overidden |
| 137 | |
| 138 | virtual void usage( void ) ; |
| 139 | |
| 140 | virtual ~UPerfTest(); |
| 141 | |
| 142 | void setCaller( UPerfTest* callingTest ); // for internal use only |
| 143 | |
| 144 | void setPath( char* path ); // for internal use only |
| 145 | |
| 146 | ULine* getLines(UErrorCode& status); |
| 147 | |
| 148 | const UChar* getBuffer(int32_t& len,UErrorCode& status); |
| 149 | |
| 150 | protected: |
| 151 | UPerfTest(int32_t argc, const char* argv[], UErrorCode& status); |
| 152 | |
| 153 | UPerfTest(int32_t argc, const char* argv[], |
| 154 | UOption addOptions[], int32_t addOptionsCount, |
| 155 | const char *addUsage, |
| 156 | UErrorCode& status); |
| 157 | |
| 158 | void init(UOption addOptions[], int32_t addOptionsCount, |
| 159 | UErrorCode& status); |
| 160 | |
| 161 | virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide ! |
| 162 | |
| 163 | virtual UBool runTestLoop( char* testname, char* par ); |
| 164 | |
| 165 | virtual UBool callTest( UPerfTest& testToBeCalled, char* par ); |
| 166 | |
| 167 | int32_t _argc; |
| 168 | const char** _argv; |
| 169 | const char * _addUsage; |
| 170 | char* resolvedFileName; |
| 171 | UCHARBUF* ucharBuf; |
| 172 | const char* encoding; |
| 173 | UBool uselen; |
| 174 | const char* fileName; |
| 175 | const char* sourceDir; |
| 176 | int32_t _remainingArgc; |
| 177 | ULine* lines; |
| 178 | int32_t numLines; |
| 179 | UBool line_mode; |
| 180 | UChar* buffer; |
| 181 | int32_t bufferLen; |
| 182 | UBool verbose; |
| 183 | UBool bulk_mode; |
| 184 | int32_t passes; |
| 185 | int32_t iterations; |
| 186 | int32_t time; |
| 187 | const char* locale; |
| 188 | private: |
| 189 | UPerfTest* caller; |
| 190 | char* path; // specifies subtests |
| 191 | |
| 192 | // static members |
| 193 | public: |
| 194 | static UPerfTest* gTest; |
| 195 | static const char gUsageString[]; |
| 196 | }; |
| 197 | |
| 198 | #endif |
| 199 | #endif |
| 200 | |