vector<unique_ptr<T>> 在 ubuntu 中占用的内存是 vector<T> 的三倍多

vector<unique_ptr<T>> takes more than three times as much memory as vector<T> in ubuntu

据我了解unique_ptr<T>not supposed有这么大的开销。

我做错了什么?

size_t t = sizeof(DataHelper::SEQ_DATA); // t = 12

std::vector<std::vector<std::unique_ptr<DataHelper::SEQ_DATA>>> d(SEQ_00_SIZE + 1); // SEQ_00_SIZE = 4540
for (unsigned int i = 0; i < d.size(); ++i) {
    for (unsigned int k = 0; k < 124668; ++k) {
        std::unique_ptr<DataHelper::SEQ_DATA> sd = std::make_unique<DataHelper::SEQ_DATA>();
        d[i].push_back(std::move(sd));
    }
}

大约需要 ~21GB 内存。

std::vector<std::vector<DataHelper::SEQ_DATA>> d(SEQ_00_SIZE + 1);
for (unsigned int i = 0; i < d.size(); ++i) {
    for (unsigned int k = 0; k < 124668; ++k) {
        DataHelper::SEQ_DATA sd;
        d[i].push_back(sd);
    }
}

大约需要 ~6,5GB 内存。

附加信息:

struct SEQ_DATA {
    uint16_t id = 0;
    uint16_t label = 0;
    float intensity = 0.0f;
    float z = 0.0f;
};

我只想有一个 vector<vector<T>> 来尽可能高效地容纳我的 4540 * 124668 个对象。我从二进制文件中读取值。由于二进制文件中的元素数量不同,我无法使用正确的数字初始化内部向量(即 124668 仅适用于第一个文件)。

gcc 9.3.0,c++ 17

"std::unique_ptr doesn't have huge overhead" 表示与指向动态分配的裸指针相比,它没有巨大的开销:

{
    auto ptr = std::make_unique<T>();
}
// has comparable cost to, and has exception safety unlike:
{
    T* ptr = new T();
    delete ptr;
}

std::unique_ptr 不会使动态分配的成本更便宜。


I just want to have a single vector<vector<T>> which holds my 4540 * 124668 objects as efficient as possible.

存储 4540 * 124668 个对象的最有效方法是平面数组:

std::vector<DataHelper::SEQ_DATA> d(4540 * 124668);

但是,考虑到内部向量不是很小,这样做的好处不一定很重要。

(i.e. 124668 is only true for the first file).

如果您不需要所有 124668 个元素,那么将未使用的元素放在向量中可能会浪费内存。