ループ内for
の動的キャストのオーバーヘッドが原因で、必要以上に時間がかかっている高価なループがあります。
コード例は次のようになります (コンパイル可能)
#include <iostream>
#include <memory>
struct Base {
virtual ~Base() {}
};
struct DerivedA : Base {};
struct DerivedB : Base {};
struct Calculator {
virtual void proceed(const DerivedA& ) const {
std::cout << "doing A stuff" << std::endl;
}
virtual void proceed(const DerivedB& ) const {
std::cout << "doing B stuff" << std::endl;
}
};
void doStuff(const std::shared_ptr<Base> &base_ptr) {
Calculator calc;
// Code that does stuff using only Base properties
for(int i = 0; i < 1000000; i++) { // expensive loop
// "redundant" dynamic cast at every iteration
auto a_ptr = std::dynamic_pointer_cast<DerivedA>(base_ptr);
if(a_ptr) calc.proceed(*a_ptr);
auto b_ptr = std::dynamic_pointer_cast<DerivedB>(base_ptr);
if(b_ptr) calc.proceed(*b_ptr);
}
}
int main() {
std::shared_ptr<Base> base_ptr = std::make_shared<DerivedA>();
doStuff(base_ptr);
}
クラスは関数内で変更されないため、ループ内でポリモーフィズムのオーバーヘッド (および分岐) を回避し、ループを複数回記述することなく単一の動的キャストと単一の関数呼び出しを実行する方法が必要であると思います.
私が考えたこと:
- 通話中にキャストし
proceed
ます。 - 来客パターン。
それらのどれもが問題を解決するとは思いません。これらは、同じことを別の方法で行っているだけです。
設計を再考することを検討していますが、その前に、このコードを改善するために必要なアイデアや提案を喜んでお聞きします.