wxWidgets/tests/benchmarks/bench.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

327 lines
8.6 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// 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());
}
}