C++ C++;:释放三维向量

C++ C++;:释放三维向量,c++,vector,C++,Vector,对于三维医学图像的slic超级像素创建,我创建了一个三维向量 (std::vector of std::vector of std::vector包含DataStr对象)。具有图像的尺寸(~150 x 150 x 150)。DataStr是一种存储体素信息的结构,例如指向同一3d向量中相邻点的指针向量。使用该方法比使用邻域迭代器或KdTree最近邻搜索在图像中循环要快得多,因为slic算法的每次迭代都必须提供该信息。此外,相比之下,使用它非常方便。但是,当3d向量超出范围时,3d向量的解除分配需

对于三维医学图像的slic超级像素创建,我创建了一个三维向量 (std::vector of std::vector of std::vector包含DataStr对象)。具有图像的尺寸(~150 x 150 x 150)。DataStr是一种存储体素信息的结构,例如指向同一3d向量中相邻点的指针向量。使用该方法比使用邻域迭代器或KdTree最近邻搜索在图像中循环要快得多,因为slic算法的每次迭代都必须提供该信息。此外,相比之下,使用它非常方便。但是,当3d向量超出范围时,3d向量的解除分配需要约4分钟。有谁能告诉我为什么会这样,我如何避免这种情况?谢谢

编辑:

第一次在这里提问,谢谢你的耐心:-)

struct DataStr{
向量邻域;
浮动cmpVal;
国际协会;
cv::Mat指数;
漂浮强度;
DataStr():关联{-1},cmpVal{std::numeric_limits::max()}{}
};
上面是.hpp文件中的结构。下面是dat的定义和初始化

std::vector<std::vector<std::vector<DataStr>>> dat;
for (int i{ 0 }; i < imgDim[0]; ++i)
{
    dat.resize(imgDim[0]);
    for (int j{ 0 }; j < imgDim[1]; ++j)
    {
        dat[i].resize(imgDim[1]);
        for (int k{ 0 }; k < imgDim[2]; ++k)
        {
            dat[i][j].resize(imgDim[2], DataStr{});
        }
    }
}
std::向量数据;
对于(int i{0};i
imgDim是图像维度的3d数组

 for (it_nImg.GoToBegin(), it_nMask.GoToBegin(), it_nCent.GoToBegin();    !it_nImg.IsAtEnd(); ++it_nImg, ++it_nMask, ++it_nCent)
{       
    auto  idx = it_nMask.GetIndex();
    DataStr* str = &dat[idx[0]][idx[1]][idx[2]];
    (*str).intensity = it_nImg.GetCenterPixel();
    (*str).index = (cv::Mat_<float>(1, 3) << idx[0], idx[1], idx[2]);

    for (int i = 0; i < it_nMask.Size(); ++i)
    {
        auto tmpIdx = it_nMask.GetIndex(i);
        (*str).neighbors.push_back(&dat[tmpIdx[0]][tmpIdx[1]][tmpIdx[2]]);
    }

}
for(it_nImg.GoToBegin()、it_nMask.GoToBegin()、it_incent.GoToBegin()!it_nImg.isattend()++it_nImg、++it_nMask、++it_incent)
{       
auto idx=it_nMask.GetIndex();
DataStr*str=&dat[idx[0]][idx[1]][idx[2]];
(*str).intensity=it_nImg.GetCenterPixel();

(*str).index=(cv::Mat_40;1,3)您提到性能问题在析构函数中。生成向量向量会导致
150+150*150
分配和解除分配。如果您在分配时没有看到它,我怀疑这是因为它在您的使用中摊销

在你的情况下,这样说可以接受吗

std::vector<DataStr> dat;
int dat_size = imgDim[0] * imgDim[1] * imgDim[2];
dat.reserve(dat_size);
// No need to loop and initialize, the default constructor
// will do that for you.
用这个

DataStr& str = dat[dat_index(idx[0], idx[1], idx[2])];
(还有一些细节,因为我使用了引用而不是指针)

inline int dat_index(int x, int y, int z) {
    return imgDim[0] * imgDim[1] * x + imgDim[0] * y + z;
}

根据您对索引的想法,这可能会略有不同。

您的问题非常模糊。也许您可以添加一个代码片段,让我们看看您在做什么?此外,您是否与使用大小为
150*150*150
的向量并提供您自己的内联索引函数
int index(x,y,z)进行过比较{返回150*150*x+150*y+z;}
?DataStr
析构函数是做什么的?类是什么样子的?请给我们看一些代码,代码显示了上千张图片。最好尝试创建一个。请编辑您的问题以添加代码或其他重要信息。至于性能问题,有一个非常简单的方法可以避免这个问题:不要通过值传递数据,但通过引用。如果这个向量只有一个,并且没有直接需要复制它,那么就不要复制它。谢谢你的回答。你的权利,对于初始化,你的方法更容易,我看不到任何缺点。你能详细说明一下“分期使用”吗?前两个代码段需要几分之一秒的时间运行。第三个代码段大约需要1分钟,但它很大程度上取决于所选的邻居(3x3x3 neigh~12s、4x4x4x4 neigh~22s、7x7x7 neigh~1min)。因此,这1分钟似乎与分配过程无关。当您分配(我猜,因为我只看到你做的一些事情),我认为所有需要分配的集合(所有第三级向量中的值)当这些向量增长到需要它们时得到分配。因此,也许你会看到20000个微小的延迟,而不是一个大的延迟。或者可能只是因为你的内存分配器分配比释放更快。这些只是猜测。顺便说一句,如果你对答案感到满意,自定义是单击“接受”复选框。它向StackOverflow发出信号,表示stion得到了回答,它会分发精灵尘埃来鼓励回答者。谢谢。这种方法将时间从230秒缩短到26秒。
DataStr& str = dat[dat_index(idx[0], idx[1], idx[2])];
inline int dat_index(int x, int y, int z) {
    return imgDim[0] * imgDim[1] * x + imgDim[0] * y + z;
}