我应该使用deque或vector在c++中存储巨大的deque吗?
Should I use a deque or vector to store huge deques in C++?
假设我有40个巨大的队列,每个队列存储用户定义类型的数据。40并不是很多,但是deques本身是巨大的(因此我选择使用deques而不是向量)。我的问题是,如果我想要一个容器来存放这40个deque,这个容器应该是矢量还是deque?
如果我选择一个向量来包含我的大deque,这会使向量在内存中很大,或者向量的元素只是指向deque ?如果包含向量变得巨大,作为存储40个巨大的deque的结果,那么我需要使用deque,而不是避免连续的内存相关的问题,我遇到当我最初选择使用deque用户定义类型容器?
例子;
class myClass {
// lots of data members resulting in large class object
}
int main(){
std::deque<myClass> foo;
for(int i=0, i<10000000, i++){
myClass classObject;
foo.push_back(classObject);
}
}
现在我们有了一个deque,其中包含了1000000个元素,其中包含了我们的类对象。假设我创建了40个这样的deque。
如果我想为这40个deque设置一个容器我应该这样做吗;
std::vector< std::deque<myClass> > bar
或者我应该这样做;
std::deque< std::deque<myClass> > bar
是否vector的元素仅仅指向deque
对于你问的问题:不。对于你的问题:是的。
在vector<deque<T>>
中,向量元素是实际的deque
对象本身,而不是指向它们的指针。但是std::deque
对象非常瘦,因为它们反过来又有指向双端数据结构的指针,其中包含队列的内容。
使用vector<deque<T>>
(甚至vector<vector<T>>
),您的40个数据集将不会在内存中彼此连续存储——只有当内部容器像std::array
一样没有分配时,所有容器的数据才会存储在一起。
另一方面,如果你真的希望你的向量元素是指向deque
对象的指针,那么你可以使用vector<unique_ptr<deque<T>>>
。
容器将其实际数据存储在Free store(堆)中的外部存储器中。因此,使用std::deque
来存储大约40个deques没有任何好处,因为它只存储deques内部管理数据,只有几个字节。所以我将使用std::vector
。
如果数字正好是 40
,那么我会考虑std::array
。
一般来说,正如教皇斯特鲁普自己所说,
我不知道你的数据结构,但我打赌
std::vector
可以打败它
意味着通常你想要线性结构,而不是链表或其他任何东西,因为通常"丰富"的计算环境(例如:pc等)非常擅长优化线性访问。
然而,如果这些携带数据的类对象都很大,我的意思是"大约和CPU缓存条目一样大",那么这不会有太大的区别。如果数据结构合适,可以使用deque(反正大多数时候都是线性的);另外,如果事先知道的话,还可以告诉它预先为1000000个元素分配内存,方法是将这个数字传递给构造函数。
无论如何,你使用的内存结构不会对你需要多少内存产生重大影响。您将需要40 * 10000000个元素。就是这样。如果这超过了你的内存,你需要获得更多的内存,或者编写一个更好的算法。
让我们考虑一下这些选项,我认为它们是:
-
std::vector<std::deque>
-
std::vector<std::deque *>
-
std::deque<std::deque>
-
std::deque<std::deque *>
container<std::deque>
&container<std::deque *>
是所有成员将连续存储(deque大部分是连续的,但不是完全连续的)。这意味着使用container<std::deque>
访问内容通常不会缓存丢失,但实际数据通过指针和will存储在对象中。而对于container<std::deque *>
,容器中的值将缓存丢失,然后在访问数据时再次缓存。
容器应该是deque还是vector取决于您是否有可能将其重新增长,以及您是否关心可变速率迭代。也就是说,vector是连续的,因此在线性迭代时不会缓存丢失,这对于deque来说是不保证的,当它跳转到子容器时,它可能会破坏预取。
编辑:我忘了提到为什么你可能更喜欢缓存丢失而不是连续性,答案是碎片。对于庞大的数据集,您给堆施加了很大的压力,增加了分配失败的机会,即使有足够的内存来存储它,因为内存分散在堆中,自定义分配器对于碎片和缓存丢失来说是一个潜在的两全美的选择。
- 在linux上调试巨大的C++项目
- Capacity of a deque
- GCC 和 Clang 代码性能的巨大差异
- 找到一种有效的方法,在 2 个巨大的缓冲区上执行 MAX,每字节字节
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- C++中deque数据结构的大O是什么?
- 如何使用C++为我的容器 Deque 设置最大大小?
- 为什么 gcc 会给我可能未初始化的警告 deque::insert 带有过滤范围
- C++ deque 消费者总是从生产者那里得到空队列
- Deque 迭代器超出范围
- C++:如何正确地将 deque::front() 返回的变量从函数中传递出去?
- 将数字提高到一个巨大的指数
- 有没有函数可以在擦除 c++ 中获取 deque.begin() 的 int 值?
- 为什么 deque 比队列快?
- 巨大的内存分配:堆栈与堆
- Deque 中元素的随机访问如何提供恒定的时间复杂度?
- 避免在使用链接列表从 deque 中删除最后一个节点时出现内存泄漏
- 初始化不是整数的巨大常量多维数组的最佳方法是什么?
- 在 v8 JavaScript 中重复调用C++是否有巨大的开销?
- 我应该使用deque或vector在c++中存储巨大的deque吗?