Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル: RWBench

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

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

## RWBench

### 形式

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

### 説明

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

  このクラスを実行するには、派生クラスのインスタンスを作成して `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 秒あたりの内部ループ演算回数を返します。