| // © 2016 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| /* |
| ********************************************************************** |
| * Copyright (c) 2002-2014, International Business Machines |
| * Corporation and others. All Rights Reserved. |
| ********************************************************************** |
| */ |
| #ifndef _UPERF_H |
| #define _UPERF_H |
| |
| #include "unicode/utypes.h" |
| #include "unicode/unistr.h" |
| #include "unicode/ustring.h" |
| |
| #include "unicode/testtype.h" |
| #include "unicode/utimer.h" |
| #include "ucbuf.h" |
| |
| // Forward declarations from uoptions.h. |
| struct UOption; |
| typedef struct UOption UOption; |
| |
| #if !UCONFIG_NO_CONVERSION |
| |
| U_NAMESPACE_USE |
| // Use the TESTCASE macro in subclasses of UPerfTest. Define the |
| // runIndexedTest method in this fashion: |
| // |
| //| void MyTest::runIndexedTest(int32_t index, UBool exec, |
| //| const char* &name, char* /*par*/) { |
| //| switch (index) { |
| //| TESTCASE(0,TestSomething); |
| //| TESTCASE(1,TestSomethingElse); |
| //| TESTCASE(2,TestAnotherThing); |
| //| default: |
| //| name = ""; |
| //| break; |
| //| } |
| //| return NULL; |
| //| } |
| #define TESTCASE(id,test) \ |
| case id: \ |
| name = #test; \ |
| if (exec) { \ |
| return test(); \ |
| } \ |
| break |
| |
| // More convenient macros. These allow easy reordering of the test cases. |
| // Copied from intltest.h, and adjusted to not logln() but return a UPerfFunction. |
| // |
| //| void MyTest::runIndexedTest(int32_t index, UBool exec, |
| //| const char* &name, char* /*par*/) { |
| //| TESTCASE_AUTO_BEGIN; |
| //| TESTCASE_AUTO(TestSomething); |
| //| TESTCASE_AUTO(TestSomethingElse); |
| //| TESTCASE_AUTO(TestAnotherThing); |
| //| TESTCASE_AUTO_END; |
| //| return NULL; |
| //| } |
| #define TESTCASE_AUTO_BEGIN \ |
| for(;;) { \ |
| int32_t testCaseAutoNumber = 0 |
| |
| #define TESTCASE_AUTO(test) \ |
| if (index == testCaseAutoNumber++) { \ |
| name = #test; \ |
| if (exec) { \ |
| return test(); \ |
| } \ |
| break; \ |
| } |
| |
| #define TESTCASE_AUTO_END \ |
| name = ""; \ |
| break; \ |
| } |
| |
| /** |
| * Subclasses of PerfTest will need to create subclasses of |
| * Function that define a call() method which contains the code to |
| * be timed. They then call setTestFunction() in their "Test..." |
| * method to establish this as the current test functor. |
| */ |
| class T_CTEST_EXPORT_API UPerfFunction { |
| public: |
| /** |
| * destructor |
| */ |
| virtual ~UPerfFunction(); |
| |
| /** |
| * Subclasses must implement this method to do the action to be |
| * measured. |
| */ |
| virtual void call(UErrorCode* status)=0; |
| |
| /** |
| * Subclasses must implement this method to return positive |
| * integer indicating the number of operations in a single |
| * call to this object's call() method. |
| */ |
| virtual long getOperationsPerIteration()=0; |
| /** |
| * Subclasses should override this method to return either positive |
| * or negative integer indicating the number of events in a single |
| * call to this object's call() method, if applicable |
| * e.g: Number of breaks / iterations for break iterator |
| */ |
| virtual long getEventsPerIteration(){ |
| return -1; |
| } |
| /** |
| * Call call() n times in a tight loop and return the elapsed |
| * milliseconds. If n is small and call() is fast the return |
| * result may be zero. Small return values have limited |
| * meaningfulness, depending on the underlying CPU and OS. |
| */ |
| virtual double time(int32_t n, UErrorCode* status) { |
| UTimer start, stop; |
| utimer_getTime(&start); |
| while (n-- > 0) { |
| call(status); |
| } |
| utimer_getTime(&stop); |
| return utimer_getDeltaSeconds(&start,&stop); // ms |
| } |
| |
| }; |
| |
| |
| class T_CTEST_EXPORT_API UPerfTest { |
| public: |
| UBool run(); |
| UBool runTest( char* name = NULL, char* par = NULL ); // not to be overidden |
| |
| virtual void usage( void ) ; |
| |
| virtual ~UPerfTest(); |
| |
| void setCaller( UPerfTest* callingTest ); // for internal use only |
| |
| void setPath( char* path ); // for internal use only |
| |
| ULine* getLines(UErrorCode& status); |
| |
| const UChar* getBuffer(int32_t& len,UErrorCode& status); |
| |
| protected: |
| UPerfTest(int32_t argc, const char* argv[], UErrorCode& status); |
| |
| UPerfTest(int32_t argc, const char* argv[], |
| UOption addOptions[], int32_t addOptionsCount, |
| const char *addUsage, |
| UErrorCode& status); |
| |
| void init(UOption addOptions[], int32_t addOptionsCount, |
| UErrorCode& status); |
| |
| virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide ! |
| |
| virtual UBool runTestLoop( char* testname, char* par ); |
| |
| virtual UBool callTest( UPerfTest& testToBeCalled, char* par ); |
| |
| int32_t _argc; |
| const char** _argv; |
| const char * _addUsage; |
| char* resolvedFileName; |
| UCHARBUF* ucharBuf; |
| const char* encoding; |
| UBool uselen; |
| const char* fileName; |
| const char* sourceDir; |
| int32_t _remainingArgc; |
| ULine* lines; |
| int32_t numLines; |
| UBool line_mode; |
| UChar* buffer; |
| int32_t bufferLen; |
| UBool verbose; |
| UBool bulk_mode; |
| int32_t passes; |
| int32_t iterations; |
| int32_t time; |
| const char* locale; |
| private: |
| UPerfTest* caller; |
| char* path; // specifies subtests |
| |
| // static members |
| public: |
| static UPerfTest* gTest; |
| static const char gUsageString[]; |
| }; |
| |
| #endif |
| #endif |
| |