为循环中多次调用的函数返回值预分配内存的正确方法是什么
What is the proper way to preallocate memory for a function return value that is called many times in a loop?
我正在尝试改进我的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);
}
}
但必须有更好的方法来做到这一点。有什么建议吗?
您可以通过传递
非常量引用来返回成员函数外部的预分配。
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
}
与建议的解决方案相比,它的优势包括:
- 按引用返回对成员函数的用户更明显
- 成员函数的功能更加包含(它不需要两种方法来执行(,这也避免了因使用不当而导致的 bug
- 类本身不太复杂
我可以看到引用返回的唯一潜在缺点是调用此方法需要额外的变量声明。
加快速度的第一步是消除每次调用f
的内存分配。 这需要一个可以重用的valarray
变量。 这可以是class C
的成员,也可以作为引用参数传入。
但是,由于valarray
乘法运算符将始终分配一个新的valarray
,因此每次调用仍然会有一个内存分配。 如果性能至关重要,则需要滚动自己的乘法循环以将结果存储到可重用数组中(可能将其大小调整为正确的大小,这对于第一次调用至关重要(。
除了不分配新内存之外,这还可能从缓存使用中提供额外的好处,因为内存是重复使用的,并且可能已经在 CPU 数据缓存中。
相关文章:
- STL算法和back_inserter可以预分配空间吗?
- 自己的自定义向量类. 内存重新分配
- 重复使用预分配的向量<复杂<double>>作为<double>长度两倍的向量
- 如何从内存中分配GDI+ POINT类地址?
- 如何将google::p rotobuf::消息直接序列化到预分配的内存中?
- 预分配的节点向量中的无锁树节点分配
- 如何使用 std::vector 防止内存重新分配
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 在预分配的内存中移动数据
- 具有预分配结果C++的重载加运算符
- 为什么分配堆内存比分配堆栈记忆更快
- C 内存地址分配
- 对内存动态分配的类不使用"*"的逻辑
- 在共享内存上分配原子
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么
- 预分配内存空间供程序使用
- 如何为正在增长的Eigen::MatrixXd预分配内存
- 管理带有预分配内存和数组的析构函数
- 通过构造函数为vector预分配内存失败
- 管理预分配块的内存管理器