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"
25 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
29 static const char OPTION_LIST
= 'l';
30 static const char OPTION_SINGLE
= '1';
32 static const char OPTION_AVG_COUNT
= 'a';
33 static const char OPTION_NUM_RUNS
= 'n';
34 static const char OPTION_NUMERIC_PARAM
= 'p';
35 static const char OPTION_STRING_PARAM
= 's';
37 // ----------------------------------------------------------------------------
38 // BenchApp declaration
39 // ----------------------------------------------------------------------------
42 typedef wxApp BenchAppBase
;
44 typedef wxAppConsole BenchAppBase
;
47 class BenchApp
: public BenchAppBase
53 virtual void OnInitCmdLine(wxCmdLineParser
& parser
);
54 virtual bool OnCmdLineParsed(wxCmdLineParser
& parser
);
55 virtual bool OnInit();
60 int GetNumericParameter() const { return m_numParam
; }
61 const wxString
& GetStringParameter() const { return m_strParam
; }
64 // list all registered benchmarks
65 void ListBenchmarks();
67 // command lines options/parameters
68 wxSortedArrayString m_toRun
;
75 IMPLEMENT_APP_CONSOLE(BenchApp
)
77 // ============================================================================
78 // Bench namespace symbols implementation
79 // ============================================================================
81 Bench::Function
*Bench::Function::ms_head
= NULL
;
83 long Bench::GetNumericParameter()
85 return wxGetApp().GetNumericParameter();
88 wxString
Bench::GetStringParameter()
90 return wxGetApp().GetStringParameter();
93 // ============================================================================
94 // BenchApp implementation
95 // ============================================================================
100 m_numRuns
= 10000; // just some default (TODO: switch to time-based one)
104 bool BenchApp::OnInit()
106 if ( !BenchAppBase::OnInit() )
109 wxPrintf("wxWidgets benchmarking program\n"
110 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE
);
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");
120 void BenchApp::OnInitCmdLine(wxCmdLineParser
& parser
)
122 BenchAppBase::OnInitCmdLine(parser
);
124 parser
.AddSwitch(OPTION_LIST
,
126 "list all the existing benchmarks");
128 parser
.AddSwitch(OPTION_SINGLE
,
130 "run the benchmark once only");
132 parser
.AddOption(OPTION_AVG_COUNT
,
136 "number of times to run benchmarking loop (default: %ld)",
139 wxCMD_LINE_VAL_NUMBER
);
140 parser
.AddOption(OPTION_NUM_RUNS
,
144 "number of times to run each benchmark in a loop "
148 wxCMD_LINE_VAL_NUMBER
);
149 parser
.AddOption(OPTION_NUMERIC_PARAM
,
153 "numeric parameter used by some benchmark functions "
157 wxCMD_LINE_VAL_NUMBER
);
158 parser
.AddOption(OPTION_STRING_PARAM
,
160 "string parameter used by some benchmark functions "
162 wxCMD_LINE_VAL_STRING
);
164 parser
.AddParam("benchmark name",
165 wxCMD_LINE_VAL_STRING
,
166 wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
);
169 bool BenchApp::OnCmdLineParsed(wxCmdLineParser
& parser
)
171 if ( parser
.Found(OPTION_LIST
) )
178 const size_t count
= parser
.GetParamCount();
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;
193 parser
.Found(OPTION_NUMERIC_PARAM
, &m_numParam
);
194 parser
.Found(OPTION_STRING_PARAM
, &m_strParam
);
195 if ( parser
.Found(OPTION_SINGLE
) )
197 if ( numRunsSpecified
)
199 wxFprintf(stderr
, "Incompatible options specified.\n");
208 // construct sorted array for quick verification of benchmark names
209 wxSortedArrayString benchmarks
;
210 for ( Bench::Function
*func
= Bench::Function::GetFirst();
212 func
= func
->GetNext() )
214 benchmarks
.push_back(func
->GetName());
217 for ( size_t n
= 0; n
< count
; n
++ )
219 const wxString name
= parser
.GetParam(n
);
220 if ( benchmarks
.Index(name
) == wxNOT_FOUND
)
222 wxFprintf(stderr
, "No benchmark named \"%s\".\n", name
);
226 m_toRun
.push_back(name
);
229 return BenchAppBase::OnCmdLineParsed(parser
);
232 int BenchApp::OnRun()
234 int rc
= EXIT_SUCCESS
;
235 for ( Bench::Function
*func
= Bench::Function::GetFirst();
237 func
= func
->GetNext() )
239 if ( m_toRun
.Index(func
->GetName()) == wxNOT_FOUND
)
244 params
+= wxString::Format(" with N=%ld", m_numParam
);
245 if ( !m_strParam
.empty() )
247 if ( !params
.empty() )
249 params
+= wxString::Format(" with s=\"%s\"", m_strParam
);
252 wxPrintf("Benchmarking %s%s: ", func
->GetName(), params
);
254 long timeMin
= LONG_MAX
,
257 bool ok
= func
->Init();
258 for ( long a
= 0; ok
&& a
< m_avgCount
; a
++ )
261 for ( long n
= 0; n
< m_numRuns
&& ok
; n
++ )
268 const long t
= sw
.Time();
285 wxPrintf("%ldms total, ", timeTotal
);
287 long times
= m_avgCount
;
288 if ( m_avgCount
> 2 )
290 timeTotal
-= timeMin
+ timeMax
;
294 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
295 (float)timeTotal
/ times
, timeMin
, timeMax
);
304 int BenchApp::OnExit()
307 delete GetTopWindow();
314 void BenchApp::ListBenchmarks()
316 wxPrintf("Available benchmarks:\n");
317 for ( Bench::Function
*func
= Bench::Function::GetFirst();
319 func
= func
->GetNext() )
321 wxPrintf("\t%s\n", func
->GetName());