我正在尝试改进我的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;
}
}
传入的数组非常大,每次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);
}
}
但必须有更好的方法来做到这一点。有什么建议?
您可以通过将非const引用传递给成员函数之外的preallocate来返回。
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;
}
}
然后调用者需要创建自己的预分配结果变量,但随后他们可以在重复调用f时重用该变量。
std::valarray<double> f_retval = std::valarray<double>(Nx);
while (/*some condition*/) {
myC.f(toModify, f_retval);
// do something with f_retval
}
这比您建议的解决方案的优势包括:
我可以看到返回引用的唯一潜在缺点是调用此方法需要额外的变量声明。
加快这一步骤的第一步是消除每次调用f
的内存分配。这需要一个可以重复使用的valarray
变量。这可以是class C
的成员,也可以作为参考参数传入。
但是,因为valarray
乘法运算符将始终分配新的valarray
,所以每次调用仍然会有内存分配。如果性能至关重要,则需要使用自己的乘法循环将结果存储到可重用数组中(可能将其调整为正确的大小,这对于第一次调用至关重要)。
除了不分配新内存之外,这还可以从缓存使用中提供额外的好处,因为内存被重用并且可能已经存在于CPU数据缓存中。