为循环中多次调用的函数返回值预分配内存的正确方法是什么?

Twe*_*lix 5 c++ optimization memory-management c++17

我试图改善我的C ++代码并试图改善我的编码风格。我想实现一个循环中多次调用的函数。

Class C {
    double alpha = 0.1;
    std::valarray<double> f(std::valarray<double> const & arr) //called many times in a loop
    {
        return arr * alpha;
    }
}
Run Code Online (Sandbox Code Playgroud)

传入的数组非常大,每次f返回时,它都会为返回值分配一个全新的数组,这确实减慢了我的代码的速度。我试图通过在执行期间一旦知道数组的大小就在它所属的类中为其预先分配一个返回值来实现修复。

Class C {
    double alpha = 0.1;
    std::valarray<double> f_retval;

    void f(std::valarray<double> const & arr) //called many times in a loop
    {
        f_retval = arr * alpha;
    }

    void allocateMembers(int Nx) //known size of the arrays used in the class 
    {
        f_retval = std::valarray<double>(Nx);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是必须有更好的方法来做到这一点。有什么建议么?

Jon*_*ard 4

您可以通过传递非常量引用到成员函数外部预分配来返回。

Class C {
    double alpha = 0.1;
    void f(std::valarray<double> const & arr, std::valarray<double>& result) //called many times in a loop
    {
        result = arr * alpha;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,调用者需要创建自己的预分配结果变量,但随后他们可以在重复调用f期间重用该变量。

std::valarray<double> f_retval = std::valarray<double>(Nx);
while (/*some condition*/) {
    myC.f(toModify, f_retval);
    // do something with f_retval
}
Run Code Online (Sandbox Code Playgroud)

与您建议的解决方案相比,它的优点包括:

  • 对于成员函数的用户来说,按引用返回更加明显
  • 成员函数的功能更加包含(不需要两个方法来执行),这也避免了使用不当引起的bug
  • 类本身不太复杂

我发现通过引用返回的唯一潜在缺点是调用此方法需要额外的变量声明。