バナーをクリックすれば目次に戻ります

Copyright 1999 Rogue Wave Software
Copyright 1999 Sun Microsystems, Inc.


RWBench

形式

#include <rw/bench.h>
(抽象基底クラス)

説明

これは抽象クラスであり、コードのベンチマークテストを自動化できます。このクラスを使用するには、仮想関数 doLoop(unsigned long N) の定義を含む RWbench からクラスを派生します。この仮想関数は、ベンチマークテストを N 回行います。あらかじめ設定された時間が経過するまで、RWBenchdoLoop() を繰り返し呼び出し、その後、実行回数を合計します。

このクラスを実行するには、派生クラスのインスタンスを作成して go() を呼び出します。その後、report() を呼び出して標準的な要約を入手します。多くのコンパイラでは、この要約にはコンパイラのタイプとメモリーモデルが自動的に含まれます。より詳細な結果を知りたいときには、ops()outerLoops() などを呼び出すことができます。

オーバーヘッドを補正したいときは、ベンチマークに関連しない部分の計算を行う idleLoop() 関数を使用します。

持続性

なし

この例では、Borland 値に対する Rogue Wave 値のハッシュ値を返すのに必要な時間のベンチマークテストを行います。

#include <rw/bench.h>                 /* ベンチマークソフトウェア */
#include <rw/cstring.h>               /* Rogue Wave 文字列クラス */
#include <stdlib.h>
#include <iostream.h>
#include <rw/ctoken.h>
#include <rw/regexp.h>

// ハッシュ対象の文字列
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";

  // 文字列検索アルゴリズムをテストする
  TestBrute other;
  other.parse(argc, argv);
  other.go();
  other.report(cout);

  // 正規表現を使った RW 検索をテストする
  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);           // オーバーヘッドを除く
  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);                // オーバーヘッドを除く
  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;
}

プログラムからの出力

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

公開コンストラクタ

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

パラメータ duration は、ベンチマークテストを行う名目上の時間数を秒で表します。仮想関数 doLoop(unsigned long) は、最低この時間が経過するまで繰り返し呼び出されます。パラメータ ILO は、実行される "内部ループ操作" 回数です。このパラメータは、doLoop(N) へパラメータ N として渡されます。パラメータ machine は、オプションとしてゼロで終了する文字列を与えるもので、テスト環境 (通常はベンチマークテストを行うハードウェア) を示します。

公開メンバー関数

virtual void
doLoop(unsigned long N)=0;

特殊化クラスによって実際の定義が提供される純粋仮想関数。指定した時間が経過するまで繰り返し呼び出され、ベンチマークテストの対象となる操作を N 回実行します。前述の例を参照してください。

double
duration() const;

ベンチマークテスト時間の現在の設定値を返します。この関数を、実際のテスト時間を返す関数 time() と混同しないでください。

virtual void
go();

ベンチマークテストを実際に実行するときは、この関数を呼び出します。

virtual void
idleLoop(unsigned long N);

この関数は、オーバーヘッドを考慮してベンチマークテストの進行を修正するのに有用です。デフォルトの定義では、"for()" ループを N 回実行するだけです。前述の例を参照してください。

const char *
machine();

この関数を使用すれば、parse() 関数によってベンチマークオブジェクトに渡された、マシン名にアクセスできます。

virtual void
parse(int argc, char* argv[]);

この関数を使用すれば、テスト時間、内部ループ回数およびマシン定義をコマンド行から簡単に変更できます。

引数 説明
argv[1] double 時間 (秒)
argv[2] unsigned long 内部ループ回数
argv[3] const char* マシン

void
parse(const char *);

これは非仮想関数で、parse(int argc, char * argv[]) と同じサービスを提供しますが、Windows ユーザー用に設計されています。Windows から提供される、ヌル文字で終了するコマンド行引数からトークンを抽出し、ANSI C コマンド引数のために仮想 parse を呼び出します。

virtual void
report(ostream&) const;

この関数で、ベンチマークテスト結果の要約を簡単に入手することができます。

double
setDuration(double t);

テスト時間を t に変更します。

unsigned long
setInnerLoops(unsigned long N);

内部ループ演算回数を N に変更します。

virtual void
what(ostream&) const;

ベンチマークテストの詳細を提供するために、この仮想関数の特殊化版を定義できます。この関数は、標準レポートの作成時に、report() によって呼び出されます。

void
where(ostream&) const;

この関数は、コードをコンパイルした環境のコンパイラとメモリーモデルに関する情報を、ストリームに出力します。

unsigned long
innerLoops() const;

内部ループ演算回数の現在の設定値を返します。この値は、関数 doLoop(unsigned long N) にパラメータ N として渡されます。

double
time() const;

オーバーヘッドを考慮して修正した、ベンチマークテスト実行時間を返します。

unsigned long
outerLoops() const;

関数 doLoop() を呼び出した回数を返します。

double
ops() const;

実行した内部ループ演算の合計回数 (outerLoop() の呼び出し回数と、呼び出しごとの内部ループ演算回数を掛けた数) を返します。

double
opsRate() const;

1 秒あたりの内部ループ演算回数を返します。