1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (C) 2001-2011 International Business Machines Corporation
4 * and others. All Rights Reserved.
5 *
6 ********************************************************************/
7/********************************************************************************
8*
9* File ubrkperf.cpp
10*
11* Modification History:
12*        Name                     Description
13*     Vladimir Weinstein          First Version, based on collperf
14*
15*********************************************************************************
16*/
17
18#include "ubrkperf.h"
19#include "uoptions.h"
20#include <stdio.h>
21
22
23#if 0
24#if U_PLATFORM_IS_DARWIN_BASED
25#include <ApplicationServices/ApplicationServices.h>
26enum{
27  kUCTextBreakAllMask = (kUCTextBreakClusterMask | kUCTextBreakWordMask | kUCTextBreakLineMask)
28    };
29UCTextBreakType breakTypes[4] = {kUCTextBreakCharMask, kUCTextBreakClusterMask, kUCTextBreakWordMask, kUCTextBreakLineMask};
30TextBreakLocatorRef breakRef;
31UCTextBreakType macBreakType;
32
33void createMACBrkIt() {
34  OSStatus status = noErr;
35  LocaleRef lref;
36  status = LocaleRefFromLocaleString(opt_locale, &lref);
37  status = UCCreateTextBreakLocator(lref, 0, kUCTextBreakAllMask, (TextBreakLocatorRef*)&breakRef);
38  if(opt_char == TRUE) {
39    macBreakType = kUCTextBreakClusterMask;
40  } else if(opt_word == TRUE) {
41    macBreakType = kUCTextBreakWordMask;
42  } else if(opt_line == TRUE) {
43    macBreakType = kUCTextBreakLineMask;
44  } else if(opt_sentence == TRUE) {
45    // error
46    // brkit = BreakIterator::createSentenceInstance(opt_locale, status);
47  } else {
48    // default is character iterator
49    macBreakType = kUCTextBreakClusterMask;
50      }
51}
52#endif
53
54
55void doForwardTest() {
56  if (opt_terse == FALSE) {
57    printf("Doing the forward test\n");
58  }
59  int32_t noBreaks = 0;
60  int32_t i = 0;
61  unsigned long startTime = timeGetTime();
62  unsigned long elapsedTime = 0;
63  if(opt_icu) {
64    createICUBrkIt();
65    brkit->setText(text);
66    brkit->first();
67    if (opt_terse == FALSE) {
68      printf("Warmup\n");
69    }
70    while(brkit->next() != BreakIterator::DONE) {
71      noBreaks++;
72    }
73
74    if (opt_terse == FALSE) {
75      printf("Measure\n");
76    }
77    startTime = timeGetTime();
78    for(i = 0; i < opt_loopCount; i++) {
79      brkit->first();
80      while(brkit->next() != BreakIterator::DONE) {
81      }
82    }
83
84    elapsedTime = timeGetTime()-startTime;
85  } else if(opt_mac) {
86#if U_PLATFORM_IS_DARWIN_BASED
87    createMACBrkIt();
88    UniChar* filePtr = text;
89    OSStatus status = noErr;
90    UniCharCount startOffset = 0, breakOffset = 0, numUniChars = textSize;
91    startOffset = 0;
92    //printf("\t---Search forward--\n");
93
94    while (startOffset < numUniChars)
95    {
96	status = UCFindTextBreak(breakRef, macBreakType, kUCTextBreakLeadingEdgeMask, filePtr, numUniChars,
97                               startOffset, &breakOffset);
98      //require_action(status == noErr, EXIT, printf( "**UCFindTextBreak failed: startOffset %d, status %d\n", (int)startOffset, (int)status));
99      //require_action((breakOffset <= numUniChars),EXIT, printf("**UCFindTextBreak breakOffset too big: startOffset %d, breakOffset %d\n", (int)startOffset, (int)breakOffset));
100
101      // Output break
102      //printf("\t%d\n", (int)breakOffset);
103
104      // Increment counters
105	noBreaks++;
106      startOffset = breakOffset;
107    }
108    startTime = timeGetTime();
109    for(i = 0; i < opt_loopCount; i++) {
110      startOffset = 0;
111
112      while (startOffset < numUniChars)
113	{
114	  status = UCFindTextBreak(breakRef, macBreakType, kUCTextBreakLeadingEdgeMask, filePtr, numUniChars,
115				   startOffset, &breakOffset);
116	  // Increment counters
117	  startOffset = breakOffset;
118	}
119    }
120    elapsedTime = timeGetTime()-startTime;
121    UCDisposeTextBreakLocator(&breakRef);
122#endif
123
124
125  }
126
127
128  if (opt_terse == FALSE) {
129  int32_t loopTime = (int)(float(1000) * ((float)elapsedTime/(float)opt_loopCount));
130      int32_t timePerCU = (int)(float(1000) * ((float)loopTime/(float)textSize));
131      int32_t timePerBreak = (int)(float(1000) * ((float)loopTime/(float)noBreaks));
132      printf("forward break iteration average loop time %d\n", loopTime);
133      printf("number of code units %d average time per code unit %d\n", textSize, timePerCU);
134      printf("number of breaks %d average time per break %d\n", noBreaks, timePerBreak);
135  } else {
136      printf("time=%d\nevents=%d\nsize=%d\n", elapsedTime, noBreaks, textSize);
137  }
138
139
140}
141
142
143
144
145#endif
146
147UPerfFunction* BreakIteratorPerformanceTest::TestICUForward()
148{
149  return new ICUForward(locale, m_mode_, m_file_, m_fileLen_);
150}
151
152UPerfFunction* BreakIteratorPerformanceTest::TestICUIsBound()
153{
154  return new ICUIsBound(locale, m_mode_, m_file_, m_fileLen_);
155}
156
157UPerfFunction* BreakIteratorPerformanceTest::TestDarwinForward()
158{
159  return NULL;
160}
161
162UPerfFunction* BreakIteratorPerformanceTest::TestDarwinIsBound()
163{
164  return NULL;
165}
166
167UPerfFunction* BreakIteratorPerformanceTest::runIndexedTest(int32_t index, UBool exec,
168												   const char *&name,
169												   char* par)
170{
171    switch (index) {
172        TESTCASE(0, TestICUForward);
173		TESTCASE(1, TestICUIsBound);
174		TESTCASE(2, TestDarwinForward);
175		TESTCASE(3, TestDarwinIsBound);
176        default:
177            name = "";
178            return NULL;
179    }
180    return NULL;
181}
182
183UOption options[]={
184                      UOPTION_DEF( "mode",        'm', UOPT_REQUIRES_ARG)
185                  };
186
187
188BreakIteratorPerformanceTest::BreakIteratorPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status)
189: UPerfTest(argc,argv,status),
190m_mode_(NULL),
191m_file_(NULL),
192m_fileLen_(0)
193{
194
195    _remainingArgc = u_parseArgs(_remainingArgc, (char**)argv, (int32_t)(sizeof(options)/sizeof(options[0])), options);
196
197
198    if(options[0].doesOccur) {
199      m_mode_ = options[0].value;
200      switch(options[0].value[0]) {
201      case 'w' :
202      case 'c' :
203      case 's' :
204      case 'l' :
205        break;
206      default:
207        status = U_ILLEGAL_ARGUMENT_ERROR;
208        break;
209      }
210    } else {
211      status = U_ILLEGAL_ARGUMENT_ERROR;
212    }
213
214    m_file_ = getBuffer(m_fileLen_, status);
215
216    if(status== U_ILLEGAL_ARGUMENT_ERROR){
217       fprintf(stderr, gUsageString, "ubrkperf");
218       fprintf(stderr, "\t-m or --mode        Required mode for breakiterator: char, word, line or sentence\n");
219
220       return;
221    }
222
223    if(U_FAILURE(status)){
224        fprintf(stderr, "FAILED to create UPerfTest object. Error: %s\n", u_errorName(status));
225        return;
226    }
227}
228
229BreakIteratorPerformanceTest::~BreakIteratorPerformanceTest()
230{
231}
232
233
234//----------------------------------------------------------------------------------------
235//
236//    Main   --  process command line, read in and pre-process the test file,
237//                 call other functions to do the actual tests.
238//
239//----------------------------------------------------------------------------------------
240int main(int argc, const char** argv) {
241    UErrorCode status = U_ZERO_ERROR;
242    BreakIteratorPerformanceTest test(argc, argv, status);
243    if(U_FAILURE(status)){
244        return status;
245    }
246    if(test.run()==FALSE){
247        fprintf(stderr,"FAILED: Tests could not be run please check the arguments.\n");
248        return -1;
249    }
250    return 0;
251}
252