Click on the banner to return to the Class Reference home page.

©Copyright 1996 Rogue Wave Software

RWBench

Synopsis

#include <rw/bench.h>
(Abstract base class)

Description

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.

Persistence

None

Example

This example benchmarks the time required to return a hash value for a Rogue Wave string versus a Borland string.

#include <rw/bench.h>                 /* Benchmark software */
#include <rw/cstring.h>               /* Rogue Wave string class */
#include <stdlib.h>
#include <iostream.h>
#include <rw/ctoken.h>
#include <rw/regexp.h>

// The string to be hashed:
const char* cs = "A multi-character string with lots of words in it to be parsed out and searched for.";

class TestBrute : public RWBench {
public:
TestBrute() { }
  virtual void       doLoop(unsigned long n);
  virtual void       idleLoop(unsigned long n);
  virtual void       what(ostream& s) const
    { s << "Brute force string search: \n"; }
};

class TestRW : public RWBench {
public:
TestRW() { }
  virtual void     doLoop(unsigned long n);
  virtual void       idleLoop(unsigned long n);
  virtual void       what(ostream& s) const
    { s << "Rogue Wave search: \n"; }
};


main(int argc, char* argv[]){
  cout << "Testing string \n\"" << cs << "\"\n";

  // Test brute force string search algorithm:
  TestBrute other;
  other.parse(argc, argv);
  other.go();
  other.report(cout);

  // Test RW searching w/regular expressions:
  TestRW rw;
  rw.parse(argc, argv);
  rw.go();
  rw.report(cout);

  return 0;
}

void TestBrute::doLoop(unsigned long n){
  RWCString string(cs);
  RWCTokenizer *tokener;
  RWCString token;

  tokener = new RWCTokenizer(string);

  while(n--){
  
    if((token = (*tokener)()).isNull())
    {
        delete tokener;
        tokener = new RWCTokenizer(string);
        token = (*tokener)();
    }

    size_t j = 0;

    for(size_t i = 0; i < string.length() && j != token.length(); 
        i++)
    {
       j = 0;
       while((j < token.length()) && (string[i+j]==token[j]))
          j++;
    }

  }
 delete tokener;
}


void TestRW::doLoop(unsigned long n){
  RWCString string(cs);
  RWCTokenizer *tokener;
  RWCString token, result;
  RWCRegexp re("");

  tokener = new RWCTokenizer(string);
  while(n--){
 
   if((token = (*tokener)()).isNull())
    {
        delete tokener;
        tokener = new RWCTokenizer(string);
        token = (*tokener)();
    }  
  re = RWCRegexp(token); 
  result = string(re);       //Do the search! 
  }
 delete tokener;
}
void TestBrute::idleLoop(unsigned long n){
  RWCString string(cs);           // Subtract out the overhead
  RWCTokenizer *tokener;
  RWCString token;

  tokener = new RWCTokenizer(string);
  
  while(n--){
  
   if((token = (*tokener)()).isNull())
    {
        delete tokener;
        tokener = new RWCTokenizer(string);
        token = (*tokener)();
    }  
  }
 delete tokener;
}

void TestRW::idleLoop(unsigned long n){
  RWCString string(cs);                //Subtract out the overhead
  RWCTokenizer *tokener;
  RWCString token, result;
  RWCRegexp re("");
  tokener = new RWCTokenizer(string);
  while(n--){
  
   if((token = (*tokener)()).isNull())
    {
        delete tokener;
        tokener = new RWCTokenizer(string);
        token = (*tokener)();
    }  
  re = RWCRegexp(token); 
  }
 delete tokener;
}

Program output:

Testing string 
"A multi-character string with lots of words in it to be parsed out and searched for."
Borland C++ V4.0 

Brute force string search: 

Iterations:                 35
Inner loop operations:      1000
Total operations:           35000
Elapsed (user) time:        4.596
Kilo-operations per second: 7.61532

Borland C++ V4.0 

Rogue Wave search: 

Iterations:                 53
Inner loop operations:      1000
Total operations:           53000
Elapsed (user) time:        2.824
Kilo-operations per second: 18.7677

Public Constructors

RWBench(double duration = 5, unsigned long ILO=1000,
        const char* machine = 0);

Public Member Functions

virtual void
doLoop(unsigned long N)=0;
double
duration() const;
virtual void
go();
virtual void
idleLoop(unsigned long N);
const char *
machine();
virtual void
parse(int argc, char* argv[]);

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 *);
virtual void
report(ostream&) const;
double
setDuration(double t);
unsigned long
setInnerLoops(unsigned long N);
virtual void
what(ostream&) const;
void
where(ostream&) const;
unsigned long
innerLoops() const;
double
time() const;
unsigned long
outerLoops() const;
double
ops() const;
double
opsRate() const;