1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/bench.cpp
3 // Purpose: Main file of the benchmarking suite
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
20 #include "wx/cmdline.h"
21 #include "wx/stopwatch.h"
29 // ----------------------------------------------------------------------------
31 // ----------------------------------------------------------------------------
33 static const char OPTION_LIST
= 'l';
34 static const char OPTION_SINGLE
= '1';
36 static const char OPTION_AVG_COUNT
= 'a';
37 static const char OPTION_NUM_RUNS
= 'n';
38 static const char OPTION_NUMERIC_PARAM
= 'p';
39 static const char OPTION_STRING_PARAM
= 's';
41 // ----------------------------------------------------------------------------
42 // BenchApp declaration
43 // ----------------------------------------------------------------------------
46 typedef wxApp BenchAppBase
;
48 typedef wxAppConsole BenchAppBase
;
51 class BenchApp
: public BenchAppBase
57 virtual void OnInitCmdLine(wxCmdLineParser
& parser
);
58 virtual bool OnCmdLineParsed(wxCmdLineParser
& parser
);
59 virtual bool OnInit();
64 int GetNumericParameter() const { return m_numParam
; }
65 const wxString
& GetStringParameter() const { return m_strParam
; }
68 // list all registered benchmarks
69 void ListBenchmarks();
71 // command lines options/parameters
72 wxSortedArrayString m_toRun
;
79 IMPLEMENT_APP_CONSOLE(BenchApp
)
81 // ============================================================================
82 // Bench namespace symbols implementation
83 // ============================================================================
85 Bench::Function
*Bench::Function::ms_head
= NULL
;
87 long Bench::GetNumericParameter()
89 return wxGetApp().GetNumericParameter();
92 wxString
Bench::GetStringParameter()
94 return wxGetApp().GetStringParameter();
97 // ============================================================================
98 // BenchApp implementation
99 // ============================================================================
104 m_numRuns
= 10000; // just some default (TODO: switch to time-based one)
108 bool BenchApp::OnInit()
110 if ( !BenchAppBase::OnInit() )
113 wxPrintf("wxWidgets benchmarking program\n"
114 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE
);
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");
124 void BenchApp::OnInitCmdLine(wxCmdLineParser
& parser
)
126 BenchAppBase::OnInitCmdLine(parser
);
128 parser
.AddSwitch(OPTION_LIST
,
130 "list all the existing benchmarks");
132 parser
.AddSwitch(OPTION_SINGLE
,
134 "run the benchmark once only");
136 parser
.AddOption(OPTION_AVG_COUNT
,
140 "number of times to run benchmarking loop (default: %ld)",
143 wxCMD_LINE_VAL_NUMBER
);
144 parser
.AddOption(OPTION_NUM_RUNS
,
148 "number of times to run each benchmark in a loop "
152 wxCMD_LINE_VAL_NUMBER
);
153 parser
.AddOption(OPTION_NUMERIC_PARAM
,
157 "numeric parameter used by some benchmark functions "
161 wxCMD_LINE_VAL_NUMBER
);
162 parser
.AddOption(OPTION_STRING_PARAM
,
164 "string parameter used by some benchmark functions "
166 wxCMD_LINE_VAL_STRING
);
168 parser
.AddParam("benchmark name",
169 wxCMD_LINE_VAL_STRING
,
170 wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
);
173 bool BenchApp::OnCmdLineParsed(wxCmdLineParser
& parser
)
175 if ( parser
.Found(OPTION_LIST
) )
182 const size_t count
= parser
.GetParamCount();
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;
197 parser
.Found(OPTION_NUMERIC_PARAM
, &m_numParam
);
198 parser
.Found(OPTION_STRING_PARAM
, &m_strParam
);
199 if ( parser
.Found(OPTION_SINGLE
) )
201 if ( numRunsSpecified
)
203 wxFprintf(stderr
, "Incompatible options specified.\n");
212 // construct sorted array for quick verification of benchmark names
213 wxSortedArrayString benchmarks
;
214 for ( Bench::Function
*func
= Bench::Function::GetFirst();
216 func
= func
->GetNext() )
218 benchmarks
.push_back(func
->GetName());
221 for ( size_t n
= 0; n
< count
; n
++ )
223 const wxString name
= parser
.GetParam(n
);
224 if ( benchmarks
.Index(name
) == wxNOT_FOUND
)
226 wxFprintf(stderr
, "No benchmark named \"%s\".\n", name
);
230 m_toRun
.push_back(name
);
233 return BenchAppBase::OnCmdLineParsed(parser
);
236 int BenchApp::OnRun()
238 int rc
= EXIT_SUCCESS
;
239 for ( Bench::Function
*func
= Bench::Function::GetFirst();
241 func
= func
->GetNext() )
243 if ( m_toRun
.Index(func
->GetName()) == wxNOT_FOUND
)
248 params
+= wxString::Format(" with N=%ld", m_numParam
);
249 if ( !m_strParam
.empty() )
251 if ( !params
.empty() )
253 params
+= wxString::Format(" with s=\"%s\"", m_strParam
);
256 wxPrintf("Benchmarking %s%s: ", func
->GetName(), params
);
258 long timeMin
= LONG_MAX
,
261 bool ok
= func
->Init();
262 for ( long a
= 0; ok
&& a
< m_avgCount
; a
++ )
265 for ( long n
= 0; n
< m_numRuns
&& ok
; n
++ )
272 const long t
= sw
.Time();
289 wxPrintf("%ldms total, ", timeTotal
);
291 long times
= m_avgCount
;
292 if ( m_avgCount
> 2 )
294 timeTotal
-= timeMin
+ timeMax
;
298 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
299 (float)timeTotal
/ times
, timeMin
, timeMax
);
308 int BenchApp::OnExit()
311 delete GetTopWindow();
318 void BenchApp::ListBenchmarks()
320 wxPrintf("Available benchmarks:\n");
321 for ( Bench::Function
*func
= Bench::Function::GetFirst();
323 func
= func
->GetNext() )
325 wxPrintf("\t%s\n", func
->GetName());