Module: Essential Tools Module Group: Miscellaneous Classes
Does not inherit
doLoop() duration() go() idleLoop() innerLoops() |
machine() ops() opsRate() outerLoops() parse() |
report() RWBench() setDuration() setInnerLoops() time() |
what() where() |
#include <rw/bench.h> (Abstract base class)
This is an abstract class that can automate the process of benchmarking a piece of code. To use it, derive a class from RWBench, including a definition for the virtual function doLoop(unsigned long N). This function should perform N operations of the type that you are trying to benchmark. RWBench will call doLoop() over and over again until a preset amount of time has elapsed. It will then sum the total number of operations performed.
To run, construct an instance of your derived class and then call go(). Then call report() to get a standard summary. For many compilers, this summary will automatically include the compiler type and memory model. You can call ops(), outerLoops(), etc. for more detail.
If you wish to correct for overhead, then provide an idleLoop() function which should do all non-benchmark-related calculations.
None
This example compares string parsing operations by benchmarking a brute force approach versus using RWCString.
#include <cstdlib> #include <iostream> #include <rw/bench.h> /* Benchmark software */ #include <rw/cstring.h> /* Rogue Wave string class */ #include <rw/ctoken.h> #include <rw/regexp.h> // The string to be hashed: static const char* g_string = "A multi-character string with lots of words " "in it to be parsed out and searched for."; struct TestBrute : public RWBench { TestBrute() { } virtual void doLoop(unsigned long); virtual void idleLoop(unsigned long); virtual void what (std::ostream& s) const { s << "Brute force string search: \n"; } }; struct TestRW : public RWBench { public: TestRW() { } virtual void doLoop(unsigned long); virtual void idleLoop(unsigned long); virtual void what (std::ostream& s) const { s << "Rogue Wave search: \n"; } }; /*****************************************************/ void TestBrute::doLoop(unsigned long n) { RWCString s (g_string); RWCTokenizer *tokener; RWCString token; tokener = new RWCTokenizer(s); while (n--) { if((token = (*tokener)()).isNull()) { delete tokener; tokener = new RWCTokenizer (s); token = (*tokener)(); } size_t j = 0; for(size_t i = 0; i < s.length() && j != token.length(); ++i) for (j = 0; (j < token.length ()) && (s [i + j] == token [j]); ++j) { } } delete tokener; } void TestRW::doLoop (unsigned long n) { RWCString s(g_string); RWCTokenizer *tokener; RWCString token, result; RWCRegexp re(""); tokener = new RWCTokenizer(s); while(n--) { if((token = (*tokener)()).isNull()) { delete tokener; tokener = new RWCTokenizer(s); token = (*tokener)(); } re = RWCRegexp(token); result = s(re); // Do the search! } delete tokener; } void TestBrute::idleLoop(unsigned long n) { // Subtract the overhead RWCString s(g_string); RWCTokenizer *tokener; RWCString token; tokener = new RWCTokenizer(s); while(n--) { if((token = (*tokener)()).isNull()) { delete tokener; tokener = new RWCTokenizer(s); token = (*tokener)(); } } delete tokener; } void TestRW::idleLoop(unsigned long n) { RWCString s(g_string); // Subtract out the overhead RWCTokenizer *tokener; RWCString token, result; RWCRegexp re(""); tokener = new RWCTokenizer(s); while(n--){ if((token = (*tokener)()).isNull()) { delete tokener; tokener = new RWCTokenizer(s); token = (*tokener)(); } re = RWCRegexp(token); } delete tokener; } /*****************************************************/ int main (int argc, char** argv) { std::cout << "Testing string \"" << g_string << "\".\n"; // Test brute force string search algorithm: TestBrute other; other.parse(argc, argv); other.go(); other.report(std::cout); // Test RW searching w/regular expressions: TestRW rw; rw.parse(argc, argv); rw.go(); rw.report(std::cout); return 0; }
Program Output:
Testing string A multi-character string with lots of words in it to be parsed out and searched for. Microsoft C/C++ Brute force string search: Iterations: 60 Inner loop operations: 1000 Total operations: 60000 Elapsed (user) time: 4.39632 Kilo-operations per second: 13.6478 Microsoft C/C++ Rogue Wave search: Iterations: 138 Inner loop operations: 1000 Total operations: 138000 Elapsed (user) time: 2.11304 Kilo-operations per second: 65.3088
RWBench(double duration = 5, unsigned long ILO=1000, const char* machine = 0);
The parameter duration is the nominal amount of time that the benchmark should take in seconds. The virtual function doLoop(unsigned long) is called over and over again until at least this amount of time has elapsed. The parameter ILO is the number of "inner loop operations" that should be performed. This parameter is passed in as parameter N to doLoop(N). Parameter machine is an optional null terminated string that should describe the test environment (perhaps the hardware the benchmark is being run on).
virtual void doLoop(unsigned long N)=0;
A pure virtual function whose actual definition should be supplied by the specializing class. This function will be repeatedly called until a time duration has elapsed. It should perform the operation to be benchmarked N times. See the example.
double duration() const;
Return the current setting for the benchmark test duration. This should not be confused with function time() which returns the actual test time.
virtual void go();
Call this function to run the benchmark.
virtual void idleLoop(unsigned long N);
This function can help to correct the benchmark for overhead. The default definition merely executes a "for()" loop N times. See the example.
const char * machine();
This function accesses the name of the machine which is passed into the benchmark object through parse().
virtual void parse(int argc, char* argv[]);
This function allows an easy way to change the test duration, number of inner loops and machine description from the command line.
Argument | Type | Description |
argv[1] | double | Duration (sec.) |
argv[2] | unsigned long | No. of inner loops |
argv[3] | const char* | Machine |
void parse(const char *);
This is a non-virtual function which provides the same service as parse(int argc, char * argv[]), but is designed for Windows users. It extracts tokens from the null-terminated command argument provided by Windows, then calls the virtual parse for ANSI C command arguments.
virtual void report(std::ostream&) const;
Calling this function provides an easy and convenient way of getting an overall summary of the results of a benchmark.
double setDuration(double t);
Change the test duration to time t.
unsigned long setInnerLoops(unsigned long N);
Change the number of "inner loop operations" to N.
virtual void what(std::ostream&) const;
You can supply a specializing version of this virtual function that provides some detail of what is being benchmarked. It is called by report() when generating a standard report.
void where(std::ostream&) const;
This function will print information to the stream about the compiler and memory model that the code was compiled under.
unsigned long innerLoops() const;
Returns the current setting for the number of inner loop operations that will be passed into function doLoop(unsigned long N) as parameter N.
double time() const;
Returns the amount of time the benchmark took, corrected for overhead.
unsigned long outerLoops() const;
Returns the number of times the function doLoop() was called.
double ops() const;
Returns the total number of inner loop operations that were performed (the product of the number of times outerLoop() was called times the number of inner loop operations performed per call).
double opsRate() const;
Returns the number of inner loop operations per second.
© Copyright Rogue Wave Software, Inc. All Rights Reserved.
Rogue Wave and SourcePro are registered trademarks of Rogue Wave Software, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.