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 license
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
20 #include "wx/cmdline.h"
21 #include "wx/stopwatch.h"
25 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
29 static const char OPTION_LIST
= 'l';
31 static const char OPTION_AVG_COUNT
= 'a';
32 static const char OPTION_NUM_RUNS
= 'n';
33 static const char OPTION_NUMERIC_PARAM
= 'p';
34 static const char OPTION_STRING_PARAM
= 's';
36 // ----------------------------------------------------------------------------
37 // BenchApp declaration
38 // ----------------------------------------------------------------------------
41 typedef wxApp BenchAppBase
;
43 typedef wxAppConsole BenchAppBase
;
46 class BenchApp
: public BenchAppBase
52 virtual void OnInitCmdLine(wxCmdLineParser
& parser
);
53 virtual bool OnCmdLineParsed(wxCmdLineParser
& parser
);
54 virtual bool OnInit();
59 int GetNumericParameter() const { return m_numParam
; }
60 const wxString
& GetStringParameter() const { return m_strParam
; }
63 // list all registered benchmarks
64 void ListBenchmarks();
66 // command lines options/parameters
67 wxSortedArrayString m_toRun
;
74 IMPLEMENT_APP_CONSOLE(BenchApp
)
76 // ============================================================================
77 // Bench namespace symbols implementation
78 // ============================================================================
80 Bench
::Function
*Bench
::Function
::ms_head
= NULL
;
82 long Bench
::GetNumericParameter()
84 return wxGetApp().GetNumericParameter();
87 wxString Bench
::GetStringParameter()
89 return wxGetApp().GetStringParameter();
92 // ============================================================================
93 // BenchApp implementation
94 // ============================================================================
99 m_numRuns
= 10000; // just some default (TODO: switch to time-based one)
103 bool BenchApp
::OnInit()
105 if ( !BenchAppBase
::OnInit() )
108 wxPrintf("wxWidgets benchmarking program\n"
109 "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE
);
112 // create a hidden parent window to be used as parent for the GUI controls
113 new wxFrame(NULL
, wxID_ANY
, "Hidden wx benchmark frame");
119 void BenchApp
::OnInitCmdLine(wxCmdLineParser
& parser
)
121 BenchAppBase
::OnInitCmdLine(parser
);
123 parser
.AddSwitch(OPTION_LIST
,
125 "list all the existing benchmarks");
127 parser
.AddOption(OPTION_AVG_COUNT
,
131 "number of times to run benchmarking loop (default: %ld)",
134 wxCMD_LINE_VAL_NUMBER
);
135 parser
.AddOption(OPTION_NUM_RUNS
,
139 "number of times to run each benchmark in a loop "
143 wxCMD_LINE_VAL_NUMBER
);
144 parser
.AddOption(OPTION_NUMERIC_PARAM
,
148 "numeric parameter used by some benchmark functions "
152 wxCMD_LINE_VAL_NUMBER
);
153 parser
.AddOption(OPTION_STRING_PARAM
,
155 "string parameter used by some benchmark functions "
157 wxCMD_LINE_VAL_STRING
);
159 parser
.AddParam("benchmark name",
160 wxCMD_LINE_VAL_STRING
,
161 wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
);
164 bool BenchApp
::OnCmdLineParsed(wxCmdLineParser
& parser
)
166 if ( parser
.Found(OPTION_LIST
) )
173 const size_t count
= parser
.GetParamCount();
183 parser
.Found(OPTION_AVG_COUNT
, &m_avgCount
);
184 parser
.Found(OPTION_NUM_RUNS
, &m_numRuns
);
185 parser
.Found(OPTION_NUMERIC_PARAM
, &m_numParam
);
186 parser
.Found(OPTION_STRING_PARAM
, &m_strParam
);
188 // construct sorted array for quick verification of benchmark names
189 wxSortedArrayString benchmarks
;
190 for ( Bench
::Function
*func
= Bench
::Function
::GetFirst();
192 func
= func
->GetNext() )
194 benchmarks
.push_back(func
->GetName());
197 for ( size_t n
= 0; n
< count
; n
++ )
199 const wxString name
= parser
.GetParam(n
);
200 if ( benchmarks
.Index(name
) == wxNOT_FOUND
)
202 wxFprintf(stderr
, "No benchmark named \"%s\".\n", name
);
206 m_toRun
.push_back(name
);
209 return BenchAppBase
::OnCmdLineParsed(parser
);
212 int BenchApp
::OnRun()
214 int rc
= EXIT_SUCCESS
;
215 for ( Bench
::Function
*func
= Bench
::Function
::GetFirst();
217 func
= func
->GetNext() )
219 if ( m_toRun
.Index(func
->GetName()) == wxNOT_FOUND
)
224 params
+= wxString
::Format(" with N=%ld", m_numParam
);
225 if ( !m_strParam
.empty() )
227 if ( !params
.empty() )
229 params
+= wxString
::Format(" with s=\"%s\"", m_strParam
);
232 wxPrintf("Benchmarking %s%s: ", func
->GetName(), params
);
234 long timeMin
= LONG_MAX
,
238 for ( long a
= 0; a
< m_avgCount
; a
++ )
241 for ( long n
= 0; n
< m_numRuns
&& ok
; n
++ )
251 const long t
= sw
.Time();
266 wxPrintf("%ldms total, ", timeTotal
);
268 long times
= m_avgCount
;
269 if ( m_avgCount
> 2 )
271 timeTotal
-= timeMin
+ timeMax
;
275 wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
276 (float)timeTotal
/ times
, timeMin
, timeMax
);
283 int BenchApp
::OnExit()
286 delete GetTopWindow();
293 void BenchApp
::ListBenchmarks()
295 wxPrintf("Available benchmarks:\n");
296 for ( Bench
::Function
*func
= Bench
::Function
::GetFirst();
298 func
= func
->GetNext() )
300 wxPrintf("\t%s\n", func
->GetName());