2

エポックからの経過時間を簡単に取得するために、次の Timer クラスがあります。

#include <chrono>

class Timer {
  public:
    void start(void);
    template <typename duration_type>
    const duration_type time_elapsed(void);
  private:
    std::chrono::high_resolution_clock::time_point epoch;
};

void Timer::start(void) {
  epoch = std::chrono::high_resolution_clock::now();
}

template <typename duration_type>
const duration_type Timer::time_elapsed(void) {
  return std::chrono::duration_cast<duration_type>(std::chrono::high_resolution_clock::now() - epoch);
}

int main(void) {
  Timer timer;

  timer.start();

  // pointless loop to cause a delay
  for (int x = 1; x < 1000000; ++x) {
    x * x * x;
  }

  std::chrono::nanoseconds elapsed = timer.time_elapsed<std::chrono::nanoseconds>();
  std::cout << elapsed.count() << std::endl;

  return 0;
}

Timer::time_elapsed() をテンプレート関数にすることでクラスが複雑になりすぎていると感じており、理想的にはその使用法を次のように簡素化したいと考えています。

  std::chrono::nanoseconds elapsed = timer.time_elapsed();
  std::cout << elapsed.count() << std::endl;
4

2 に答える 2

4

コードのいくつかを修正し、 の適切な使用法を追加しましstd::chronoた。変更リストには次のものが含まれます。

  1. 関数呼び出しからすべての引数を削除しまし(void)た。C++ の方法ではないためです :-)
  2. また、C++ では必要ないものも削除return 0;しましmain()た。これは、コンパイラがそれを配置するためです。
  3. 現在の実装で高品質の時計を見つけるのは本当に難しいかもしれないので、私は時計を型定義しました。ここで私の答えを見てください。基本的に、今はカスタム クロックを使用することをお勧めします。typedefリファクタリングのおかげで、将来的にはより簡単になる可能性があります。
  4. 待機ループを C++11 スリープ インターフェイスに変更しました (必要に応じて、そこで時間をランダム化できます - C++11 でも :-) )。std::chronoその場合、その変更は必要ありませんでしたが、スレッドライブラリでも使用されていることをうまく示しています。
  5. メソッドの実装をクラス内に配置して、コンパイラにそれらをインライン化する機会を与えます。inlineまたは、クラス外の実装でキーワードの明示性を使用することもできます。
  6. 私はあなたのtime_elapsed()方法を作りましたconst
  7. constメソッドの戻り値から不要なものを削除time_elapsed()し、一方でそのメソッドの使用に追加しました。その正確な場所constで十分だからです。
  8. 大事なことを言い忘れましたが、メソッドを変更して、time_elapsed()時計のネイティブ解像度を で返すようにしましたreturn。ここでデータを失うことはないため、はるかに優れたソリューションです。特定の単位(つまり、私たち)のユーザーにデータを提供するときに、それを緩めたい場合があります。そこを使用duration_castして、一部のデータを失うことに同意し、解決策で十分であることをコンパイラーに伝える必要があります。

以下のコードと上記の変更があなたにとって興味深いものになることを願っています。

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::chrono;

class Timer {
public:
  typedef high_resolution_clock Clock;
  void start()
  { epoch = Clock::now(); }
  Clock::duration time_elapsed() const
  { return Clock::now() - epoch; }
private:
  Clock::time_point epoch;
};

int main() {
  Timer timer;
  timer.start();

  // sleep some time
  std::this_thread::sleep_for(microseconds(40));

  const auto elapsed = timer.time_elapsed();
  std::cout << duration_cast<microseconds>(elapsed).count() << "us" << std::endl;
}

ところで、私はクラス インターフェイスをいじりたくありませんでした (すでにあまりにも多くの変更を加えました)。まだそのインターフェースに縛られていない場合は、@sehe が提案したものに従うことをお勧めします。doubleしかし、それを戻り値として使用しないでください;-)

于 2012-11-17T18:31:42.880 に答える
1

now-epoch()を格納し、経過時間から演算子Tに高精度キャストを実行するヘルパークラスを返します。または、time_elapsed_in_units<T>経過時間のように見えるメソッドを作成し、経過時間が演算子Tの単位で呼び出す構造体を返すようにします。

ヘルパークラスの演算子Tのオーバーロードにより、呼び出された人が暗黙的に必要とするタイプを検出できます。

于 2012-11-17T14:08:08.610 に答える