rebaked makefiles with 0.2.4
[wxWidgets.git] / tests / benchmarks / bench.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/bench.cpp
3 // Purpose: Main file of the benchmarking suite
4 // Author: Vadim Zeitlin
5 // Created: 2008-07-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/app.h"
20 #include "wx/cmdline.h"
21 #include "wx/stopwatch.h"
22
23 #include "bench.h"
24
25 // ----------------------------------------------------------------------------
26 // constants
27 // ----------------------------------------------------------------------------
28
29 static const char OPTION_LIST = 'l';
30
31 static const char OPTION_AVG_COUNT = 'a';
32 static const char OPTION_NUM_RUNS = 'n';
33 static const char OPTION_NUMERIC_PARAM = 'p';
34
35 // ----------------------------------------------------------------------------
36 // BenchApp declaration
37 // ----------------------------------------------------------------------------
38
39 #if wxUSE_GUI
40 typedef wxApp BenchAppBase;
41 #else
42 typedef wxAppConsole BenchAppBase;
43 #endif
44
45 class BenchApp : public BenchAppBase
46 {
47 public:
48 BenchApp();
49
50 // standard overrides
51 virtual void OnInitCmdLine(wxCmdLineParser& parser);
52 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
53 virtual bool OnInit();
54 virtual int OnRun();
55 virtual int OnExit();
56
57 // accessor
58 int GetNumericParameter() const { return m_numParam; }
59
60 private:
61 // list all registered benchmarks
62 void ListBenchmarks();
63
64 // command lines options/parameters
65 wxSortedArrayString m_toRun;
66 long m_numRuns,
67 m_avgCount,
68 m_numParam;
69 };
70
71 IMPLEMENT_APP_CONSOLE(BenchApp)
72
73 // ============================================================================
74 // Bench namespace symbols implementation
75 // ============================================================================
76
77 Bench::Function *Bench::Function::ms_head = NULL;
78
79 long Bench::GetNumericParameter()
80 {
81 return wxGetApp().GetNumericParameter();
82 }
83
84 // ============================================================================
85 // BenchApp implementation
86 // ============================================================================
87
88 BenchApp::BenchApp()
89 {
90 m_avgCount = 10;
91 m_numRuns = 10000; // just some default (TODO: switch to time-based one)
92 m_numParam = 1;
93 }
94
95 bool BenchApp::OnInit()
96 {
97 if ( !BenchAppBase::OnInit() )
98 return false;
99
100 wxPrintf("wxWidgets benchmarking program\n"
101 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE);
102
103 #if wxUSE_GUI
104 // create a hidden parent window to be used as parent for the GUI controls
105 new wxFrame(NULL, wxID_ANY, "Hidden wx benchmark frame");
106 #endif // wxUSE_GUI
107
108 return true;
109 }
110
111 void BenchApp::OnInitCmdLine(wxCmdLineParser& parser)
112 {
113 BenchAppBase::OnInitCmdLine(parser);
114
115 parser.AddSwitch(OPTION_LIST,
116 "list",
117 "list all the existing benchmarks");
118
119 parser.AddOption(OPTION_AVG_COUNT,
120 "avg-count",
121 wxString::Format
122 (
123 "number of times to run benchmarking loop (default: %ld)",
124 m_avgCount
125 ),
126 wxCMD_LINE_VAL_NUMBER);
127 parser.AddOption(OPTION_NUM_RUNS,
128 "num-runs",
129 wxString::Format
130 (
131 "number of times to run each benchmark in a loop "
132 "(default: %ld)",
133 m_numRuns
134 ),
135 wxCMD_LINE_VAL_NUMBER);
136 parser.AddOption(OPTION_NUMERIC_PARAM,
137 "num-param",
138 "numeric parameter used by some benchmark functions "
139 "(default: 1)",
140 wxCMD_LINE_VAL_NUMBER);
141
142 parser.AddParam("benchmark name",
143 wxCMD_LINE_VAL_STRING,
144 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
145 }
146
147 bool BenchApp::OnCmdLineParsed(wxCmdLineParser& parser)
148 {
149 if ( parser.Found(OPTION_LIST) )
150 {
151 ListBenchmarks();
152
153 return false;
154 }
155
156 const size_t count = parser.GetParamCount();
157 if ( !count )
158 {
159 parser.Usage();
160
161 ListBenchmarks();
162
163 return false;
164 }
165
166 parser.Found(OPTION_AVG_COUNT, &m_avgCount);
167 parser.Found(OPTION_NUM_RUNS, &m_numRuns);
168 parser.Found(OPTION_NUMERIC_PARAM, &m_numParam);
169
170 // construct sorted array for quick verification of benchmark names
171 wxSortedArrayString benchmarks;
172 for ( Bench::Function *func = Bench::Function::GetFirst();
173 func;
174 func = func->GetNext() )
175 {
176 benchmarks.push_back(func->GetName());
177 }
178
179 for ( size_t n = 0; n < count; n++ )
180 {
181 const wxString name = parser.GetParam(n);
182 if ( benchmarks.Index(name) == wxNOT_FOUND )
183 {
184 wxFprintf(stderr, "No benchmark named \"%s\".\n", name);
185 return false;
186 }
187
188 m_toRun.push_back(name);
189 }
190
191 return BenchAppBase::OnCmdLineParsed(parser);
192 }
193
194 int BenchApp::OnRun()
195 {
196 int rc = EXIT_SUCCESS;
197 for ( Bench::Function *func = Bench::Function::GetFirst();
198 func;
199 func = func->GetNext() )
200 {
201 if ( m_toRun.Index(func->GetName()) == wxNOT_FOUND )
202 continue;
203
204 wxPrintf("Benchmarking %s(%ld): ", func->GetName(), m_numParam);
205
206 long timeMin = LONG_MAX,
207 timeMax = 0,
208 timeTotal = 0;
209 bool ok = true;
210 for ( long a = 0; a < m_avgCount; a++ )
211 {
212 wxStopWatch sw;
213 for ( long n = 0; n < m_numRuns && ok; n++ )
214 {
215 ok = func->Run();
216 }
217
218 sw.Pause();
219
220 if ( !ok )
221 break;
222
223 const long t = sw.Time();
224 if ( t < timeMin )
225 timeMin = t;
226 if ( t > timeMax )
227 timeMax = t;
228 timeTotal += t;
229 }
230
231 if ( !ok )
232 {
233 wxPrintf("ERROR\n");
234 rc = EXIT_FAILURE;
235 }
236 else
237 {
238 wxPrintf("%ldms total, ", timeTotal);
239
240 long times = m_avgCount;
241 if ( m_avgCount > 2 )
242 {
243 timeTotal -= timeMin + timeMax;
244 times -= 2;
245 }
246
247 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
248 (float)timeTotal / times, timeMin, timeMax);
249 }
250 }
251
252 return rc;
253 }
254
255 int BenchApp::OnExit()
256 {
257 #if wxUSE_GUI
258 delete GetTopWindow();
259 #endif // wxUSE_GUI
260
261 return 0;
262 }
263
264 /* static */
265 void BenchApp::ListBenchmarks()
266 {
267 wxPrintf("Available benchmarks:\n");
268 for ( Bench::Function *func = Bench::Function::GetFirst();
269 func;
270 func = func->GetNext() )
271 {
272 wxPrintf("\t%s\n", func->GetName());
273 }
274 }