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