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