1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/bench.cpp
3 // Purpose: Main file of the benchmarking suite
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #include "wx/cmdline.h"
20 #include "wx/stopwatch.h"
28 // ----------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
32 static const char OPTION_LIST
= 'l';
33 static const char OPTION_SINGLE
= '1';
35 static const char OPTION_AVG_COUNT
= 'a';
36 static const char OPTION_NUM_RUNS
= 'n';
37 static const char OPTION_NUMERIC_PARAM
= 'p';
38 static const char OPTION_STRING_PARAM
= 's';
40 // ----------------------------------------------------------------------------
41 // BenchApp declaration
42 // ----------------------------------------------------------------------------
45 typedef wxApp BenchAppBase
;
47 typedef wxAppConsole BenchAppBase
;
50 class BenchApp
: public BenchAppBase
56 virtual void OnInitCmdLine(wxCmdLineParser
& parser
);
57 virtual bool OnCmdLineParsed(wxCmdLineParser
& parser
);
58 virtual bool OnInit();
63 int GetNumericParameter() const { return m_numParam
; }
64 const wxString
& GetStringParameter() const { return m_strParam
; }
67 // list all registered benchmarks
68 void ListBenchmarks();
70 // command lines options/parameters
71 wxSortedArrayString m_toRun
;
78 IMPLEMENT_APP_CONSOLE(BenchApp
)
80 // ============================================================================
81 // Bench namespace symbols implementation
82 // ============================================================================
84 Bench::Function
*Bench::Function::ms_head
= NULL
;
86 long Bench::GetNumericParameter()
88 return wxGetApp().GetNumericParameter();
91 wxString
Bench::GetStringParameter()
93 return wxGetApp().GetStringParameter();
96 // ============================================================================
97 // BenchApp implementation
98 // ============================================================================
103 m_numRuns
= 10000; // just some default (TODO: switch to time-based one)
107 bool BenchApp::OnInit()
109 if ( !BenchAppBase::OnInit() )
112 wxPrintf("wxWidgets benchmarking program\n"
113 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE
);
116 // create a hidden parent window to be used as parent for the GUI controls
117 new wxFrame(NULL
, wxID_ANY
, "Hidden wx benchmark frame");
123 void BenchApp::OnInitCmdLine(wxCmdLineParser
& parser
)
125 BenchAppBase::OnInitCmdLine(parser
);
127 parser
.AddSwitch(OPTION_LIST
,
129 "list all the existing benchmarks");
131 parser
.AddSwitch(OPTION_SINGLE
,
133 "run the benchmark once only");
135 parser
.AddOption(OPTION_AVG_COUNT
,
139 "number of times to run benchmarking loop (default: %ld)",
142 wxCMD_LINE_VAL_NUMBER
);
143 parser
.AddOption(OPTION_NUM_RUNS
,
147 "number of times to run each benchmark in a loop "
151 wxCMD_LINE_VAL_NUMBER
);
152 parser
.AddOption(OPTION_NUMERIC_PARAM
,
156 "numeric parameter used by some benchmark functions "
160 wxCMD_LINE_VAL_NUMBER
);
161 parser
.AddOption(OPTION_STRING_PARAM
,
163 "string parameter used by some benchmark functions "
165 wxCMD_LINE_VAL_STRING
);
167 parser
.AddParam("benchmark name",
168 wxCMD_LINE_VAL_STRING
,
169 wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
);
172 bool BenchApp::OnCmdLineParsed(wxCmdLineParser
& parser
)
174 if ( parser
.Found(OPTION_LIST
) )
181 const size_t count
= parser
.GetParamCount();
191 bool numRunsSpecified
= false;
192 if ( parser
.Found(OPTION_AVG_COUNT
, &m_avgCount
) )
193 numRunsSpecified
= true;
194 if ( parser
.Found(OPTION_NUM_RUNS
, &m_numRuns
) )
195 numRunsSpecified
= true;
196 parser
.Found(OPTION_NUMERIC_PARAM
, &m_numParam
);
197 parser
.Found(OPTION_STRING_PARAM
, &m_strParam
);
198 if ( parser
.Found(OPTION_SINGLE
) )
200 if ( numRunsSpecified
)
202 wxFprintf(stderr
, "Incompatible options specified.\n");
211 // construct sorted array for quick verification of benchmark names
212 wxSortedArrayString benchmarks
;
213 for ( Bench::Function
*func
= Bench::Function::GetFirst();
215 func
= func
->GetNext() )
217 benchmarks
.push_back(func
->GetName());
220 for ( size_t n
= 0; n
< count
; n
++ )
222 const wxString name
= parser
.GetParam(n
);
223 if ( benchmarks
.Index(name
) == wxNOT_FOUND
)
225 wxFprintf(stderr
, "No benchmark named \"%s\".\n", name
);
229 m_toRun
.push_back(name
);
232 return BenchAppBase::OnCmdLineParsed(parser
);
235 int BenchApp::OnRun()
237 int rc
= EXIT_SUCCESS
;
238 for ( Bench::Function
*func
= Bench::Function::GetFirst();
240 func
= func
->GetNext() )
242 if ( m_toRun
.Index(func
->GetName()) == wxNOT_FOUND
)
247 params
+= wxString::Format(" with N=%ld", m_numParam
);
248 if ( !m_strParam
.empty() )
250 if ( !params
.empty() )
252 params
+= wxString::Format(" with s=\"%s\"", m_strParam
);
255 wxPrintf("Benchmarking %s%s: ", func
->GetName(), params
);
257 long timeMin
= LONG_MAX
,
260 bool ok
= func
->Init();
261 for ( long a
= 0; ok
&& a
< m_avgCount
; a
++ )
264 for ( long n
= 0; n
< m_numRuns
&& ok
; n
++ )
271 const long t
= sw
.Time();
288 wxPrintf("%ldms total, ", timeTotal
);
290 long times
= m_avgCount
;
291 if ( m_avgCount
> 2 )
293 timeTotal
-= timeMin
+ timeMax
;
297 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
298 (float)timeTotal
/ times
, timeMin
, timeMax
);
307 int BenchApp::OnExit()
310 delete GetTopWindow();
317 void BenchApp::ListBenchmarks()
319 wxPrintf("Available benchmarks:\n");
320 for ( Bench::Function
*func
= Bench::Function::GetFirst();
322 func
= func
->GetNext() )
324 wxPrintf("\t%s\n", func
->GetName());