Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to preallocate memory for a function return value that is called many times in a loop?

I'm trying to improve my c++ code and trying to improve my coding style. I want to implement this function that is called multiple times in a loop.

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

the array passed in is quite large and every time f returns it allocates a brand new array for the return value, really slowing down my code. I've tried to implement a fix by preallocating a return value for it in the class it is a member of as soon as the size of the arrays are known during execution;

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);
    }
}

But there must be a better way to do this. Any suggestions?

like image 980
Tweelix Avatar asked Apr 28 '19 16:04

Tweelix


Video Answer


1 Answers

You could return by passing by non-const reference to preallocate outside of the member function.

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;
    }
}

The caller would then need to create their own preallocated result variable, but then they could reuse that variable during repeated calls to f.

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

The advantages that this has over the solution that you suggested include:

  • the return-by-reference is more obvious to the user of the member function
  • the member function's functionality is more contained (it doesn't require two methods to execute), which also avoids bugs caused by improper usage
  • the class itself is less complex

The only potential drawback I can see with return-by-reference is that calling this method requires an extra variable declaration.

like image 91
Jonathan Heard Avatar answered Oct 09 '22 21:10

Jonathan Heard