我预先分配了一个由N个变量组成的大向量,作为函数A起作用的complex<double>
。完成后,我希望将其传递给另一个函数B,在该函数中我希望重新使用该内存分配,但要使用长度为2N的向量,数据类型为double
,即:
vector<complex<double>> vec(N);
for (int i = 0; i < M; i++;
{
Function A(&vec); // Does work on vec as a vector<complex<double>>
// vector<complex<double>> vec(N) converts to vector<double> vec(2N) (or vector<float> vec(4N))
Function B(&vec); // Does work on vec as a vector<double> or vector<float>
}
其中M
和N
足够大,可以保证预先分配vec
。我试图避免分配,因为这很昂贵。数据彼此独立(即在功能B中使用该数据之前,我将再次填充该数据)。根据到目前为止的读物,(匿名?)工会似乎是要走的路,但是我不确定工会在矢量方面的工作方式。我希望我能在这件事上得到一些帮助。
谢谢。
编辑::分配向量需要3秒,而该函数需要5秒才能操作。
答案 0 :(得分:4)
您正在尝试重用原始内存,而不是向量-那么为什么不这样做,并避免弄乱类型呢?
写一个预分配并拥有内存的池分配器。
使用该池分配器(的代理)构造第一个vector<complex>
。
后来在第一个向量被销毁并放弃了对池的所有权之后,使用相同的池分配器(作为其代理)创建一个vector<double>
。
该向量将复制顶级分配器对象,这就是为什么它必须是保留对您预先分配的持久性池的引用的代理的原因。
答案 1 :(得分:1)
我看到以下解决方案:
1。变体-现代工会
使用vector< variant< double, complex<double> > >
。这可以存储double
或complex<double>
元素。
即使变体类型(double
和complex<double>
)可以共享空间,由于在给定时间只有一种类型处于活动状态,您仍然不知道它们的执行效率(还有需要是一个标识符来标记哪种类型是活动的,对齐8字节边界可能会浪费50%的空间)。另请参见here。
此外,即使容器在任何给定时刻具有相同类型的所有元素,您也必须区分每个元素。
2。使用原始内存
更传统的选择是使用operator new()
(函数,而不是运算符)分配内存。然后,您可以使用Placement New在此处构造双精度和复数,并使用显式析构函数调用销毁它们。
如果您不需要许多std::vector
功能(例如动态增长,删除,插入),而只需要一个大数据存储,那么这可能是一个有效的解决方案。在这种情况下,唯一需要的就是尺寸。
不用担心范围,可以使用自定义删除器将所有内容打包到std::unique_ptr
中。删除程序将只调用operator delete()
。
3。编写自定义分配器
std::vector
使用分配器的第二个模板参数。分配器允许您自定义从何处获取内存。但是有很多要实现的标准,并且标准对该行为强加了一些规则。