2

クラス構成で実行時のパフォーマンスを理解しようとして、次のテスト コードを作成しました。その中で、関数をクラスのメンバー関数として直接呼び出す場合と、元のクラスをメンバーとして持つ複合クラスを介して呼び出す場合の時間を比較しています。

メソッドには同等の時間がかかるように思われますが、そうではありません。複合クラスを介して呼び出すと、ほぼ 2 倍の時間がかかります。

コードは次のとおりです。

const int REPS(1e8);
const double INPUT(5.29);

class Base {
public:
  inline double BaseFunc(double x) const;
};

double Base::BaseFunc(double x) const {
  return 2.718*x + 3.14;
};

class Super {
public:
  inline double BaseFunc(double x) const;
private:
  Base b_; 
};

double Super::BaseFunc(double x) const {
  return b_.BaseFunc(x);
};

int main() {
  auto t0 = std::chrono::high_resolution_clock::now();

  // Construct objects.
  Base b;
  Super s;

  // Call to base directly.
  for (int i = 0; i < REPS; ++i)
    b.BaseFunc(INPUT);
  auto t1 = std::chrono::high_resolution_clock::now();

  // Call to base through composited class.
  for (int i = 0; i < REPS; ++i)
    s.BaseFunc(INPUT);
  auto t2 = std::chrono::high_resolution_clock::now();

  // Find average durations.
  auto diff1 = std::chrono::duration_cast<std::chrono::nanoseconds>(t1-t0).count();
  diff1 /= REPS;
  auto diff2 = std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
  diff2 /= REPS;

  std::cout << "Calling directly to base took " << diff1 << "nsec.\n";
  std::cout << "Calling to base through a composited class took " << diff2 << "nsec.\n";
}

-std=c++11 -O0 -Winline を指定して g++ バージョン 4.7.2 でコンパイルすると、次のようになります。

Calling directly to base took 13nsec.
Calling to base through a composited class took 24nsec.

本質的に同じ関数を呼び出すこれら 2 つの方法の間に、なぜこのような違いがあるのでしょうか? すべてがインライン化されているため (gcc はそれ以外のことを教えてくれません)、これらは同じものであるはずです。

私はこれについて完全に間違って考えていますか?どんな助けでも大歓迎です!ありがとう!

更新助けてくれてありがとう!私は戻って、関数呼び出し (ベクトルで inner_product を呼び出す) にさらに追加し、繰り返しごとにすべての結果を使用して、gcc が何も最適化していないことを確認しました。次に、最適化をオンにしました。あなたは皆正しかった:違いはなくなった.

私は次の 2 つの重要なことを学んだと思います: 1) 最適化をオフにすると、gcc はインライン化を試みることさえしないため、-Winline フラグは無意味であり、2) 関数を呼び出すこれら 2 つの方法には意味のある違いはありません。他のクラス内からメンバー関数を自信を持って呼び出すことができます!

再度、感謝します!

4

3 に答える 3