]> git.saurik.com Git - wxWidgets.git/blame - tests/benchmarks/bench.cpp
updating the comment as well
[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';
33
34// ----------------------------------------------------------------------------
35// BenchApp declaration
36// ----------------------------------------------------------------------------
37
38#if wxUSE_GUI
39 typedef wxApp BenchAppBase;
40#else
41 typedef wxAppConsole BenchAppBase;
42#endif
43
44class BenchApp : public BenchAppBase
45{
46public:
47 BenchApp();
48
49 // standard overrides
50 virtual void OnInitCmdLine(wxCmdLineParser& parser);
51 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
52 virtual bool OnInit();
53 virtual int OnRun();
54 virtual int OnExit();
55
56private:
57 // list all registered benchmarks
58 void ListBenchmarks();
59
60 // command lines options/parameters
61 wxSortedArrayString m_toRun;
62 long m_numRuns,
63 m_avgCount;
64};
65
66// ============================================================================
67// Bench::Function implementation
68// ============================================================================
69
70Bench::Function *Bench::Function::ms_head = NULL;
71
72// ============================================================================
73// BenchApp implementation
74// ============================================================================
75
76IMPLEMENT_APP_CONSOLE(BenchApp)
77
78BenchApp::BenchApp()
79{
80 m_avgCount = 10;
81 m_numRuns = 10000; // just some default (TODO: switch to time-based one)
82}
83
84bool BenchApp::OnInit()
85{
86 if ( !BenchAppBase::OnInit() )
87 return false;
88
89 wxPrintf("wxWidgets benchmarking program\n"
90 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE);
91
92#if wxUSE_GUI
93 // create a hidden parent window to be used as parent for the GUI controls
94 new wxFrame(NULL, wxID_ANY, "Hidden wx benchmark frame");
95#endif // wxUSE_GUI
96
97 return true;
98}
99
100void BenchApp::OnInitCmdLine(wxCmdLineParser& parser)
101{
102 BenchAppBase::OnInitCmdLine(parser);
103
104 parser.AddSwitch(OPTION_LIST,
105 "list",
106 "list all the existing benchmarks");
107
108 parser.AddOption(OPTION_AVG_COUNT,
109 "avg-count",
c517ecec
VZ
110 wxString::Format
111 (
112 "number of times to run benchmarking loop (default: %ld)",
113 m_avgCount
114 ),
dc2ae355
VZ
115 wxCMD_LINE_VAL_NUMBER);
116 parser.AddOption(OPTION_NUM_RUNS,
117 "num-runs",
c517ecec
VZ
118 wxString::Format
119 (
120 "number of times to run each benchmark in a loop "
121 "(default: %ld)",
122 m_numRuns
123 ),
dc2ae355
VZ
124 wxCMD_LINE_VAL_NUMBER);
125 parser.AddParam("benchmark name",
126 wxCMD_LINE_VAL_STRING,
127 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
128}
129
130bool BenchApp::OnCmdLineParsed(wxCmdLineParser& parser)
131{
132 if ( parser.Found(OPTION_LIST) )
133 {
134 ListBenchmarks();
135
136 return false;
137 }
138
139 const size_t count = parser.GetParamCount();
140 if ( !count )
141 {
142 parser.Usage();
143
144 ListBenchmarks();
145
146 return false;
147 }
148
149 parser.Found(OPTION_AVG_COUNT, &m_avgCount);
150 parser.Found(OPTION_NUM_RUNS, &m_numRuns);
151
152 // construct sorted array for quick verification of benchmark names
153 wxSortedArrayString benchmarks;
154 for ( Bench::Function *func = Bench::Function::GetFirst();
155 func;
156 func = func->GetNext() )
157 {
158 benchmarks.push_back(func->GetName());
159 }
160
161 for ( size_t n = 0; n < count; n++ )
162 {
163 const wxString name = parser.GetParam(n);
164 if ( benchmarks.Index(name) == wxNOT_FOUND )
165 {
166 wxFprintf(stderr, "No benchmark named \"%s\".\n", name);
167 return false;
168 }
169
170 m_toRun.push_back(name);
171 }
172
173 return BenchAppBase::OnCmdLineParsed(parser);
174}
175
176int BenchApp::OnRun()
177{
178 int rc = EXIT_SUCCESS;
179 for ( Bench::Function *func = Bench::Function::GetFirst();
180 func;
181 func = func->GetNext() )
182 {
183 if ( m_toRun.Index(func->GetName()) == wxNOT_FOUND )
184 continue;
185
186 wxPrintf("Benchmarking %s: ", func->GetName());
187
188 long timeMin = LONG_MAX,
189 timeMax = 0,
190 timeTotal = 0;
191 bool ok = true;
192 for ( long a = 0; a < m_avgCount; a++ )
193 {
194 wxStopWatch sw;
195 for ( long n = 0; n < m_numRuns && ok; n++ )
196 {
197 ok = func->Run();
198 }
199
200 sw.Pause();
201
202 if ( !ok )
203 break;
204
205 const long t = sw.Time();
206 if ( t < timeMin )
207 timeMin = t;
208 if ( t > timeMax )
209 timeMax = t;
210 timeTotal += t;
211 }
212
213 if ( !ok )
214 {
215 wxPrintf("ERROR\n");
216 rc = EXIT_FAILURE;
217 }
218 else
219 {
220 wxPrintf("%ldms total, ", timeTotal);
221
222 long times = m_avgCount;
223 if ( m_avgCount > 2 )
224 {
225 timeTotal -= timeMin + timeMax;
226 times -= 2;
227 }
228
229 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
230 (float)timeTotal / times, timeMin, timeMax);
231 }
232 }
233
234 return rc;
235}
236
237int BenchApp::OnExit()
238{
239#if wxUSE_GUI
240 delete GetTopWindow();
241#endif // wxUSE_GUI
242
243 return 0;
244}
245
246/* static */
247void BenchApp::ListBenchmarks()
248{
249 wxPrintf("Available benchmarks:\n");
250 for ( Bench::Function *func = Bench::Function::GetFirst();
251 func;
252 func = func->GetNext() )
253 {
254 wxPrintf("\t%s\n", func->GetName());
255 }
256}