| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: tests/benchmarks/bench.cpp
- // Purpose: Main file of the benchmarking suite
- // Author: Vadim Zeitlin
- // Created: 2008-07-19
- // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- // ============================================================================
- // declarations
- // ============================================================================
- // ----------------------------------------------------------------------------
- // headers
- // ----------------------------------------------------------------------------
- #include "wx/app.h"
- #include "wx/cmdline.h"
- #include "wx/stopwatch.h"
- #if wxUSE_GUI
- #include "wx/frame.h"
- #endif
- #include "bench.h"
- // ----------------------------------------------------------------------------
- // constants
- // ----------------------------------------------------------------------------
- static const char OPTION_LIST = 'l';
- static const char OPTION_SINGLE = '1';
- static const char OPTION_AVG_COUNT = 'a';
- static const char OPTION_NUM_RUNS = 'n';
- static const char OPTION_NUMERIC_PARAM = 'p';
- static const char OPTION_STRING_PARAM = 's';
- // ----------------------------------------------------------------------------
- // BenchApp declaration
- // ----------------------------------------------------------------------------
- #if wxUSE_GUI
- typedef wxApp BenchAppBase;
- #else
- typedef wxAppConsole BenchAppBase;
- #endif
- class BenchApp : public BenchAppBase
- {
- public:
- BenchApp();
- // standard overrides
- virtual void OnInitCmdLine(wxCmdLineParser& parser);
- virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
- virtual bool OnInit();
- virtual int OnRun();
- virtual int OnExit();
- // accessors
- int GetNumericParameter() const { return m_numParam; }
- const wxString& GetStringParameter() const { return m_strParam; }
- private:
- // list all registered benchmarks
- void ListBenchmarks();
- // command lines options/parameters
- wxSortedArrayString m_toRun;
- long m_numRuns,
- m_avgCount,
- m_numParam;
- wxString m_strParam;
- };
- IMPLEMENT_APP_CONSOLE(BenchApp)
- // ============================================================================
- // Bench namespace symbols implementation
- // ============================================================================
- Bench::Function *Bench::Function::ms_head = NULL;
- long Bench::GetNumericParameter()
- {
- return wxGetApp().GetNumericParameter();
- }
- wxString Bench::GetStringParameter()
- {
- return wxGetApp().GetStringParameter();
- }
- // ============================================================================
- // BenchApp implementation
- // ============================================================================
- BenchApp::BenchApp()
- {
- m_avgCount = 10;
- m_numRuns = 10000; // just some default (TODO: switch to time-based one)
- m_numParam = 0;
- }
- bool BenchApp::OnInit()
- {
- if ( !BenchAppBase::OnInit() )
- return false;
- wxPrintf("wxWidgets benchmarking program\n"
- "Build: %s\n", WX_BUILD_OPTIONS_SIGNATURE);
- #if wxUSE_GUI
- // create a hidden parent window to be used as parent for the GUI controls
- new wxFrame(NULL, wxID_ANY, "Hidden wx benchmark frame");
- #endif // wxUSE_GUI
- return true;
- }
- void BenchApp::OnInitCmdLine(wxCmdLineParser& parser)
- {
- BenchAppBase::OnInitCmdLine(parser);
- parser.AddSwitch(OPTION_LIST,
- "list",
- "list all the existing benchmarks");
- parser.AddSwitch(OPTION_SINGLE,
- "single",
- "run the benchmark once only");
- parser.AddOption(OPTION_AVG_COUNT,
- "avg-count",
- wxString::Format
- (
- "number of times to run benchmarking loop (default: %ld)",
- m_avgCount
- ),
- wxCMD_LINE_VAL_NUMBER);
- parser.AddOption(OPTION_NUM_RUNS,
- "num-runs",
- wxString::Format
- (
- "number of times to run each benchmark in a loop "
- "(default: %ld)",
- m_numRuns
- ),
- wxCMD_LINE_VAL_NUMBER);
- parser.AddOption(OPTION_NUMERIC_PARAM,
- "num-param",
- wxString::Format
- (
- "numeric parameter used by some benchmark functions "
- "(default: %ld)",
- m_numParam
- ),
- wxCMD_LINE_VAL_NUMBER);
- parser.AddOption(OPTION_STRING_PARAM,
- "str-param",
- "string parameter used by some benchmark functions "
- "(default: empty)",
- wxCMD_LINE_VAL_STRING);
- parser.AddParam("benchmark name",
- wxCMD_LINE_VAL_STRING,
- wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
- }
- bool BenchApp::OnCmdLineParsed(wxCmdLineParser& parser)
- {
- if ( parser.Found(OPTION_LIST) )
- {
- ListBenchmarks();
- return false;
- }
- const size_t count = parser.GetParamCount();
- if ( !count )
- {
- parser.Usage();
- ListBenchmarks();
- return false;
- }
- bool numRunsSpecified = false;
- if ( parser.Found(OPTION_AVG_COUNT, &m_avgCount) )
- numRunsSpecified = true;
- if ( parser.Found(OPTION_NUM_RUNS, &m_numRuns) )
- numRunsSpecified = true;
- parser.Found(OPTION_NUMERIC_PARAM, &m_numParam);
- parser.Found(OPTION_STRING_PARAM, &m_strParam);
- if ( parser.Found(OPTION_SINGLE) )
- {
- if ( numRunsSpecified )
- {
- wxFprintf(stderr, "Incompatible options specified.\n");
- return false;
- }
- m_avgCount =
- m_numRuns = 1;
- }
- // construct sorted array for quick verification of benchmark names
- wxSortedArrayString benchmarks;
- for ( Bench::Function *func = Bench::Function::GetFirst();
- func;
- func = func->GetNext() )
- {
- benchmarks.push_back(func->GetName());
- }
- for ( size_t n = 0; n < count; n++ )
- {
- const wxString name = parser.GetParam(n);
- if ( benchmarks.Index(name) == wxNOT_FOUND )
- {
- wxFprintf(stderr, "No benchmark named \"%s\".\n", name);
- return false;
- }
- m_toRun.push_back(name);
- }
- return BenchAppBase::OnCmdLineParsed(parser);
- }
- int BenchApp::OnRun()
- {
- int rc = EXIT_SUCCESS;
- for ( Bench::Function *func = Bench::Function::GetFirst();
- func;
- func = func->GetNext() )
- {
- if ( m_toRun.Index(func->GetName()) == wxNOT_FOUND )
- continue;
- wxString params;
- if ( m_numParam )
- params += wxString::Format(" with N=%ld", m_numParam);
- if ( !m_strParam.empty() )
- {
- if ( !params.empty() )
- params += " and";
- params += wxString::Format(" with s=\"%s\"", m_strParam);
- }
- wxPrintf("Benchmarking %s%s: ", func->GetName(), params);
- long timeMin = LONG_MAX,
- timeMax = 0,
- timeTotal = 0;
- bool ok = func->Init();
- for ( long a = 0; ok && a < m_avgCount; a++ )
- {
- wxStopWatch sw;
- for ( long n = 0; n < m_numRuns && ok; n++ )
- {
- ok = func->Run();
- }
- sw.Pause();
- const long t = sw.Time();
- if ( t < timeMin )
- timeMin = t;
- if ( t > timeMax )
- timeMax = t;
- timeTotal += t;
- }
- func->Done();
- if ( !ok )
- {
- wxPrintf("ERROR\n");
- rc = EXIT_FAILURE;
- }
- else
- {
- wxPrintf("%ldms total, ", timeTotal);
- long times = m_avgCount;
- if ( m_avgCount > 2 )
- {
- timeTotal -= timeMin + timeMax;
- times -= 2;
- }
- wxPrintf("%.2f avg (min=%ld, max=%ld)\n",
- (float)timeTotal / times, timeMin, timeMax);
- }
- fflush(stdout);
- }
- return rc;
- }
- int BenchApp::OnExit()
- {
- #if wxUSE_GUI
- delete GetTopWindow();
- #endif // wxUSE_GUI
- return 0;
- }
- /* static */
- void BenchApp::ListBenchmarks()
- {
- wxPrintf("Available benchmarks:\n");
- for ( Bench::Function *func = Bench::Function::GetFirst();
- func;
- func = func->GetNext() )
- {
- wxPrintf("\t%s\n", func->GetName());
- }
- }
|