]> git.saurik.com Git - wxWidgets.git/blame - tests/benchmarks/bench.cpp
Implement monitoring of file descriptors in wxMotif event loop.
[wxWidgets.git] / tests / benchmarks / bench.cpp
CommitLineData
dc2ae355
VZ
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>
526954c5 8// Licence: wxWindows licence
dc2ae355
VZ
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
7b363ab6
VZ
23#if wxUSE_GUI
24 #include "wx/frame.h"
25#endif
26
dc2ae355
VZ
27#include "bench.h"
28
29// ----------------------------------------------------------------------------
30// constants
31// ----------------------------------------------------------------------------
32
33static const char OPTION_LIST = 'l';
139ea30e 34static const char OPTION_SINGLE = '1';
dc2ae355
VZ
35
36static const char OPTION_AVG_COUNT = 'a';
37static const char OPTION_NUM_RUNS = 'n';
8fad8b2e 38static const char OPTION_NUMERIC_PARAM = 'p';
ebfa7cea 39static const char OPTION_STRING_PARAM = 's';
dc2ae355
VZ
40
41// ----------------------------------------------------------------------------
42// BenchApp declaration
43// ----------------------------------------------------------------------------
44
45#if wxUSE_GUI
46 typedef wxApp BenchAppBase;
47#else
48 typedef wxAppConsole BenchAppBase;
49#endif
50
51class BenchApp : public BenchAppBase
52{
53public:
54 BenchApp();
55
56 // standard overrides
57 virtual void OnInitCmdLine(wxCmdLineParser& parser);
58 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
59 virtual bool OnInit();
60 virtual int OnRun();
61 virtual int OnExit();
62
ebfa7cea 63 // accessors
8fad8b2e 64 int GetNumericParameter() const { return m_numParam; }
ebfa7cea 65 const wxString& GetStringParameter() const { return m_strParam; }
8fad8b2e 66
dc2ae355
VZ
67private:
68 // list all registered benchmarks
69 void ListBenchmarks();
70
71 // command lines options/parameters
72 wxSortedArrayString m_toRun;
73 long m_numRuns,
8fad8b2e
VZ
74 m_avgCount,
75 m_numParam;
ebfa7cea 76 wxString m_strParam;
dc2ae355
VZ
77};
78
8fad8b2e
VZ
79IMPLEMENT_APP_CONSOLE(BenchApp)
80
dc2ae355 81// ============================================================================
8fad8b2e 82// Bench namespace symbols implementation
dc2ae355
VZ
83// ============================================================================
84
85Bench::Function *Bench::Function::ms_head = NULL;
86
8fad8b2e
VZ
87long Bench::GetNumericParameter()
88{
89 return wxGetApp().GetNumericParameter();
90}
91
ebfa7cea
VZ
92wxString Bench::GetStringParameter()
93{
94 return wxGetApp().GetStringParameter();
95}
96
dc2ae355
VZ
97// ============================================================================
98// BenchApp implementation
99// ============================================================================
100
dc2ae355
VZ
101BenchApp::BenchApp()
102{
103 m_avgCount = 10;
104 m_numRuns = 10000; // just some default (TODO: switch to time-based one)
ebfa7cea 105 m_numParam = 0;
dc2ae355
VZ
106}
107
108bool BenchApp::OnInit()
109{
110 if ( !BenchAppBase::OnInit() )
111 return false;
112
113 wxPrintf("wxWidgets benchmarking program\n"
114 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE);
115
116#if wxUSE_GUI
117 // create a hidden parent window to be used as parent for the GUI controls
118 new wxFrame(NULL, wxID_ANY, "Hidden wx benchmark frame");
119#endif // wxUSE_GUI
120
121 return true;
122}
123
124void BenchApp::OnInitCmdLine(wxCmdLineParser& parser)
125{
126 BenchAppBase::OnInitCmdLine(parser);
127
128 parser.AddSwitch(OPTION_LIST,
129 "list",
130 "list all the existing benchmarks");
131
139ea30e
VZ
132 parser.AddSwitch(OPTION_SINGLE,
133 "single",
134 "run the benchmark once only");
135
dc2ae355
VZ
136 parser.AddOption(OPTION_AVG_COUNT,
137 "avg-count",
c517ecec
VZ
138 wxString::Format
139 (
140 "number of times to run benchmarking loop (default: %ld)",
141 m_avgCount
142 ),
dc2ae355
VZ
143 wxCMD_LINE_VAL_NUMBER);
144 parser.AddOption(OPTION_NUM_RUNS,
145 "num-runs",
c517ecec
VZ
146 wxString::Format
147 (
148 "number of times to run each benchmark in a loop "
149 "(default: %ld)",
150 m_numRuns
151 ),
dc2ae355 152 wxCMD_LINE_VAL_NUMBER);
8fad8b2e
VZ
153 parser.AddOption(OPTION_NUMERIC_PARAM,
154 "num-param",
ebfa7cea
VZ
155 wxString::Format
156 (
157 "numeric parameter used by some benchmark functions "
158 "(default: %ld)",
159 m_numParam
160 ),
8fad8b2e 161 wxCMD_LINE_VAL_NUMBER);
ebfa7cea
VZ
162 parser.AddOption(OPTION_STRING_PARAM,
163 "str-param",
164 "string parameter used by some benchmark functions "
165 "(default: empty)",
166 wxCMD_LINE_VAL_STRING);
8fad8b2e 167
dc2ae355
VZ
168 parser.AddParam("benchmark name",
169 wxCMD_LINE_VAL_STRING,
170 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
171}
172
173bool BenchApp::OnCmdLineParsed(wxCmdLineParser& parser)
174{
175 if ( parser.Found(OPTION_LIST) )
176 {
177 ListBenchmarks();
178
179 return false;
180 }
181
182 const size_t count = parser.GetParamCount();
183 if ( !count )
184 {
185 parser.Usage();
186
187 ListBenchmarks();
188
189 return false;
190 }
191
139ea30e
VZ
192 bool numRunsSpecified = false;
193 if ( parser.Found(OPTION_AVG_COUNT, &m_avgCount) )
194 numRunsSpecified = true;
195 if ( parser.Found(OPTION_NUM_RUNS, &m_numRuns) )
196 numRunsSpecified = true;
8fad8b2e 197 parser.Found(OPTION_NUMERIC_PARAM, &m_numParam);
ebfa7cea 198 parser.Found(OPTION_STRING_PARAM, &m_strParam);
139ea30e
VZ
199 if ( parser.Found(OPTION_SINGLE) )
200 {
201 if ( numRunsSpecified )
202 {
203 wxFprintf(stderr, "Incompatible options specified.\n");
204
205 return false;
206 }
207
208 m_avgCount =
209 m_numRuns = 1;
210 }
dc2ae355
VZ
211
212 // construct sorted array for quick verification of benchmark names
213 wxSortedArrayString benchmarks;
214 for ( Bench::Function *func = Bench::Function::GetFirst();
215 func;
216 func = func->GetNext() )
217 {
218 benchmarks.push_back(func->GetName());
219 }
220
221 for ( size_t n = 0; n < count; n++ )
222 {
223 const wxString name = parser.GetParam(n);
224 if ( benchmarks.Index(name) == wxNOT_FOUND )
225 {
226 wxFprintf(stderr, "No benchmark named \"%s\".\n", name);
227 return false;
228 }
229
230 m_toRun.push_back(name);
231 }
232
233 return BenchAppBase::OnCmdLineParsed(parser);
234}
235
236int BenchApp::OnRun()
237{
238 int rc = EXIT_SUCCESS;
239 for ( Bench::Function *func = Bench::Function::GetFirst();
240 func;
241 func = func->GetNext() )
242 {
243 if ( m_toRun.Index(func->GetName()) == wxNOT_FOUND )
244 continue;
245
ebfa7cea
VZ
246 wxString params;
247 if ( m_numParam )
248 params += wxString::Format(" with N=%ld", m_numParam);
249 if ( !m_strParam.empty() )
250 {
251 if ( !params.empty() )
252 params += " and";
253 params += wxString::Format(" with s=\"%s\"", m_strParam);
254 }
255
256 wxPrintf("Benchmarking %s%s: ", func->GetName(), params);
dc2ae355
VZ
257
258 long timeMin = LONG_MAX,
259 timeMax = 0,
260 timeTotal = 0;
fa8825a0
VZ
261 bool ok = func->Init();
262 for ( long a = 0; ok && a < m_avgCount; a++ )
dc2ae355
VZ
263 {
264 wxStopWatch sw;
265 for ( long n = 0; n < m_numRuns && ok; n++ )
266 {
267 ok = func->Run();
268 }
269
270 sw.Pause();
271
dc2ae355
VZ
272 const long t = sw.Time();
273 if ( t < timeMin )
274 timeMin = t;
275 if ( t > timeMax )
276 timeMax = t;
277 timeTotal += t;
278 }
279
fa8825a0
VZ
280 func->Done();
281
dc2ae355
VZ
282 if ( !ok )
283 {
284 wxPrintf("ERROR\n");
285 rc = EXIT_FAILURE;
286 }
287 else
288 {
289 wxPrintf("%ldms total, ", timeTotal);
290
291 long times = m_avgCount;
292 if ( m_avgCount > 2 )
293 {
294 timeTotal -= timeMin + timeMax;
295 times -= 2;
296 }
297
298 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
299 (float)timeTotal / times, timeMin, timeMax);
300 }
ad1ca296
VZ
301
302 fflush(stdout);
dc2ae355
VZ
303 }
304
305 return rc;
306}
307
308int BenchApp::OnExit()
309{
310#if wxUSE_GUI
311 delete GetTopWindow();
312#endif // wxUSE_GUI
313
314 return 0;
315}
316
317/* static */
318void BenchApp::ListBenchmarks()
319{
320 wxPrintf("Available benchmarks:\n");
321 for ( Bench::Function *func = Bench::Function::GetFirst();
322 func;
323 func = func->GetNext() )
324 {
325 wxPrintf("\t%s\n", func->GetName());
326 }
327}