]> git.saurik.com Git - wxWidgets.git/blame - tests/benchmarks/bench.cpp
add appearance tag to book controls
[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';
30
31static const char OPTION_AVG_COUNT = 'a';
32static const char OPTION_NUM_RUNS = 'n';
8fad8b2e 33static const char OPTION_NUMERIC_PARAM = 'p';
dc2ae355
VZ
34
35// ----------------------------------------------------------------------------
36// BenchApp declaration
37// ----------------------------------------------------------------------------
38
39#if wxUSE_GUI
40 typedef wxApp BenchAppBase;
41#else
42 typedef wxAppConsole BenchAppBase;
43#endif
44
45class BenchApp : public BenchAppBase
46{
47public:
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
8fad8b2e
VZ
57 // accessor
58 int GetNumericParameter() const { return m_numParam; }
59
dc2ae355
VZ
60private:
61 // list all registered benchmarks
62 void ListBenchmarks();
63
64 // command lines options/parameters
65 wxSortedArrayString m_toRun;
66 long m_numRuns,
8fad8b2e
VZ
67 m_avgCount,
68 m_numParam;
dc2ae355
VZ
69};
70
8fad8b2e
VZ
71IMPLEMENT_APP_CONSOLE(BenchApp)
72
dc2ae355 73// ============================================================================
8fad8b2e 74// Bench namespace symbols implementation
dc2ae355
VZ
75// ============================================================================
76
77Bench::Function *Bench::Function::ms_head = NULL;
78
8fad8b2e
VZ
79long Bench::GetNumericParameter()
80{
81 return wxGetApp().GetNumericParameter();
82}
83
dc2ae355
VZ
84// ============================================================================
85// BenchApp implementation
86// ============================================================================
87
dc2ae355
VZ
88BenchApp::BenchApp()
89{
90 m_avgCount = 10;
91 m_numRuns = 10000; // just some default (TODO: switch to time-based one)
8fad8b2e 92 m_numParam = 1;
dc2ae355
VZ
93}
94
95bool 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
111void 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",
c517ecec
VZ
121 wxString::Format
122 (
123 "number of times to run benchmarking loop (default: %ld)",
124 m_avgCount
125 ),
dc2ae355
VZ
126 wxCMD_LINE_VAL_NUMBER);
127 parser.AddOption(OPTION_NUM_RUNS,
128 "num-runs",
c517ecec
VZ
129 wxString::Format
130 (
131 "number of times to run each benchmark in a loop "
132 "(default: %ld)",
133 m_numRuns
134 ),
dc2ae355 135 wxCMD_LINE_VAL_NUMBER);
8fad8b2e
VZ
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
dc2ae355
VZ
142 parser.AddParam("benchmark name",
143 wxCMD_LINE_VAL_STRING,
144 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
145}
146
147bool 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);
8fad8b2e 168 parser.Found(OPTION_NUMERIC_PARAM, &m_numParam);
dc2ae355
VZ
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
194int 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
8fad8b2e 204 wxPrintf("Benchmarking %s(%ld): ", func->GetName(), m_numParam);
dc2ae355
VZ
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
255int BenchApp::OnExit()
256{
257#if wxUSE_GUI
258 delete GetTopWindow();
259#endif // wxUSE_GUI
260
261 return 0;
262}
263
264/* static */
265void 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}