鉴于内存开销对我的应用程序至关重要,我认为上面两个选项中,后者将更轻量级。我对么?我的基础是,向量的内存开销为4个指针,以跟踪begin()
,end()
,size()
和分配器。所以整个模型的总大小将是
(4*sizeof(T*) + sizeof(T)*Ni)*No + 3*sizeof(std::vector<T>*)
在这里,我假设Ni
,No
是内部和外部向量中的元素数量。通过使用后一个表达式,我希望保存4*sizeof(T*)*No
,因为在我的应用程序中,No
是巨大的,而Ni <<<< No
。只是为了解决问题,No
的顺序为100
百万及以上,Ni
的顺序通常为3
到50
。
提前感谢您的兴趣和想法。
注意:我理解并且非常乐意支付处理指针的价格。分配,遍历和解除分配,我可以在没有任何重大性能开销的情况下这样做。
答案 0 :(得分:2)
实际上是4,你错过了分配器。见What is the overhead cost of an empty vector?
取决于您的申请。 你永远不会附加内部向量吗? 他们都有相同数量的元素吗? 内部向量中存储的数据的平均大小是否很小?
如果您对上述所有问题的回答都是肯定的,那么T*
可能是一个可接受的解决方案。
如果不考虑如何在没有矢量支持的情况下处理该问题。记住内存可能更容易。
答案 1 :(得分:1)
如您所见here,std::vector
的确切开销取决于实现。
另请注意,如果No
非常大,则很可能在某些实现中您的数据将以块的形式存储,在这种情况下,您还需要具有块数量级的开销。
但总的来说,我同意指针实现在空间方面更便宜。
答案 2 :(得分:1)
我认为[
vector<T*>
会更好。我是对的吗?
它会更小,但不一定“更好”。这种变化会让你有必要分配和释放内部数组。你将无法知道内部数组的大小。
另请注意,大小上的一些开销将保留:只要您的内部数组是单独分配的,除了请求的块的大小之外,分配器还会保留一些额外的存储空间,以便让释放例程知道大小大块的。
如果你的内存要求太紧,可以考虑为整个数组分配一个向量,然后将各个块分成一个指针向量。这将消除单独分配内部数组的每块开销。
答案 3 :(得分:1)
如果您担心向量的开销,您还应该关注malloc()
/ new
的开销:典型的内存分配器开销是每个内存区域至少两个指针,带来一个小vector<>
的开销,最多五个指针(在Linux上为sizeof(vector<int>) == 3*sizeof(void*)
)。
所以,我要做的是问自己,内部数组的大小是否需要在初始化后更改。如果可以避免以后重新分配那些数组,我会分配一大块内存,然后我可以分配到不同的内部数组,只存储它们的位置:
int** pointerArray = new int*[innerArrayCount + 1];
int* store = new int[totalSizeOfInnerArrays];
for(int* nextArray = store, i = 0; i <= innerArrayCount; i++) {
pointerArray[i] = nextArray;
nextArray += innerArraySize[i];
}
然后可以从下一个指针和它自己的指针的差异推导出数组的大小:
for(int i = 0; i < innerArrayCount; i++) {
int* curArray = pointerArray[i];
size_t curSize = pointerArray[i + 1] - pointerArray[i];
//Do whatever you like with curArray.
}
或者,您可以直接使用该结束指针迭代内部数组:
for(int i = 0; i < innerArrayCount; i++) {
for(int* iterator = pointerArray[i]; iterator < pointerArray[i + 1]; iterator++) {
//Do whatever you like with *iterator.
}
}