我有一个昂贵的循环,由于循环内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
通话中投射。 - 访客模式。
我认为他们中的任何一个都不能解决问题。这些只是做同一件事的不同方式。
我正在考虑重新考虑我的设计,但在此之前,我很乐意听到您可能需要改进这段代码的任何想法和建议。