gpt4 book ai didi

c++ - 循环内不变多态类型的优化

转载 作者:行者123 更新时间:2023-11-28 03:05:45 25 4
gpt4 key购买 nike

我有一个昂贵的 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);
}

由于类在函数内部没有改变,我认为必须有一种方法来避免循环内部的多态开销(和分支)并执行单个动态转换和单个无需多次编写循环的函数调用。

我的想法:

  1. proceed 调用中进行转换。
  2. 访客模式。

我认为他们中的任何一个都不能解决问题。这些只是做同一件事的不同方式。

我正在考虑重新考虑我的设计,但在此之前,我很乐意听到您可能需要改进这段代码的任何想法和建议。

最佳答案

首先,我宁愿按照 Baldrick 在对 OP 的评论中建议的那样去做,然后我会尝试 OP 中引用的其他替代方案。我每次都会分析/测量结果以做出明智的决定。

如果您还不满意,那么我建议您遵循以下思路:

template <typename T>
void doStuffImpl(const T &obj) {
Calculator calc;
for(int i = 0; i < 1000000; i++)
calc.proceed(obj);
}

void doStuff(const std::shared_ptr<Base> &base_ptr) {

auto a_ptr = std::dynamic_pointer_cast<DerivedA>(base_ptr);
if (a_ptr)
doStuffImpl(*a_ptr);

auto b_ptr = std::dynamic_pointer_cast<DerivedB>(base_ptr);
if (b_ptr)
doStuffImpl(*b_ptr);
}

关于c++ - 循环内不变多态类型的优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19792645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com