c++ - 如何在需要时将C++中的计算推迟?

标签 c++ performance deferred-execution

在C++(*)中,是否可以有一种结构将“计算”推迟到需要时才进行(如果不需要,可能永远不进行计算)?我的用例如下:我大约有十二个bool变量,每个变量都是通过一些函数调用来计算的。接下来,有一个相当长(且复杂)的条件语句,该语句以不同组合使用这些 bool(boolean) 变量来确定代码下一步将采取什么措施。
这是一些人为设计的示例代码,希望可以更好地说明我在做什么:

bool const b1 = func1(param1,param2,param3);
bool const b2 = func2(param4);
// ...
bool const b15 = func15(param35,param36,param37,param38);

if (b1 && !b5 && (b2 || b3)) { do_something1(); }
else if (b3 && !b15 || (b4 && b9 && b6)) { do_something2(); }
else if (b14 || b10 || (!b11 && b7)) { do_something3(); }
else if (b8) {
    if (!b1 || !b6) { do_something4(); }
    else if ( /* ... */ ) // ... etc
}
// ... and on and on
那是一个纯粹的人为例子,但希望它能说明这个想法。
显然,可以不使用 bool(boolean) 值来重写此代码,而直接在大条件语句中调用这些函数。但是我觉得这将使原本不易阅读的代码更加难以阅读,并且更容易出错。而且这种逻辑可能会改变,所以我认为从重构的 Angular 来看, bool(boolean) 值也使管理起来更加容易。
此外,任何 bool(boolean) 值都可以在条件中多次引用。因此,直接使用功能意味着可以重复执行。 (我在考虑std::bind可能会从可读性的 Angular 帮助我;但是它仍然可能多次调用任何funcN()。)
我要寻找的是两个词中最好的,例如“延迟”计算。如果不是在代码开始时进行明确的计算和分配,该怎么办呢?我可以说,“仅根据需要对它们进行评估(并记住结果)”。通常,并不是所有的 bool(boolean) 值实际上都需要计算以确定下一步会发生什么,这是有条件的大声明。这里的目标是提高性能,因为该代码经常被调用。因此,我试图减少每次迭代完成的工作量。
(*)最好是C++ 14(或更旧的版本),因为那是我的雇主所使用的。
编辑:像这样的事情:
#include <iostream>
#include <functional>

//////////////////////////////////////////////////////////////////////////////
class Sum
{
    public:
        int sum(int const a, int const b) { ++n_calls_; return (a+b); }
        int getNCalls() const { return n_calls_; }

    private:
        int n_calls_ = 0;
};

//////////////////////////////////////////////////////////////////////////////
template <class BoundFunc, typename RetType>
class DeferredCompute
{
    public:
        DeferredCompute(BoundFunc const& f) : func_(f) { }

        RetType operator()()
        {
            if (!computed_)
            {
                value_ = func_();
                computed_ = true;
            }
            return value_;
        }

    private:
        bool             computed_ = false;
        RetType          value_;
        BoundFunc const& func_;
};

//////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
    Sum s;
    auto boundSum = std::bind(&Sum::sum, &s, 75, 25);

    DeferredCompute<decltype(boundSum), int> deferredSum(boundSum);

    // call function directly repeatedly
    for (int i=0; i<5; ++i)
    {
      std::cout << "boundSum()=" << boundSum() << std::endl;
    }
    std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;

    // should only call once
    for (int i=0; i<5; ++i)
    {
      std::cout << "deferredSum()=" << deferredSum() << std::endl;
    }
    std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;

    return 0;
}
输出:
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
s.getNCalls()=5
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
s.getNCalls()=6

最佳答案

您正在寻找带有选项std::launch::deferred的std::async。
https://en.cppreference.com/w/cpp/thread/async
例如

auto future = std::async(std::launch::deferred, [](){return 5;});
// future isn't calculated yet

auto result = future.get();
// result = 5, and will remain cached while in scope.

关于c++ - 如何在需要时将C++中的计算推迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63909372/

相关文章:

具有日期范围和时间步长的 MySQL 查询性能

performance - 如何计算A-star算法的运行时间

Javascript/AngularJS - 等待回调完成执行

C++ - 从两侧搜索数组

c++ - 将函数指针存储到任何成员函数

c++ - 列出驱动器中的所有文件数量不相等?

c++ - Qt - QTextStream - 如何将光标位置设置为一行的开头?

python - 如何在 Python 中创建具有相应索引条件的 bool 矩阵?

c# - 如何在条件语句中使用 Linq 的 .Count() 方法

go - golang defer 是如何循环工作的?