summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/tools/ctestfw/unicode/uperf.h
blob: e578c4669458446130bd079be7f8e2be2e1dec85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// © 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 nullptr;
//| }
#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 nullptr;
//| }
#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 = nullptr, char* par = nullptr ); // not to be overridden
        
    virtual void usage() ;
    
    virtual ~UPerfTest();

    void setCaller( UPerfTest* callingTest ); // for internal use only
    
    void setPath( char* path ); // for internal use only
    
    ULine* getLines(UErrorCode& status);

    const char16_t* 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 = nullptr ); // override !

    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;
    char16_t* 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