我正在使用队列和优先队列,计划快速地处理大量数据。
因此,我希望我的队列和优先队列能够对添加和删除操作进行响应。
使用向量(vector)、列表(list)或双端队列(deque)作为底层容器有什么相对优点呢?
更新: 在撰写本文时,Mike Seymour和Steve Townsend的回答都值得一读。谢谢两位!
std :: queue
:
- std::deque
通常是最佳选择; 它支持所有必要的操作,并随着增长以块状方式分配内存。
- std::list
也支持必要的操作,但由于存在更多的内存分配,可能速度较慢; 在特殊情况下,您可以通过从专用对象池中分配来获得良好的结果,但这不完全简单。
- std::vector
不能用作它没有pop_front()
操作; 这样的操作将很慢,因为它必须移动所有剩余的元素。std :: array
或您不重新调整大小的std :: vector
)。 您需要处理它填满的情况,可以通过报告错误或分配更大的缓冲区并复制所有数据来处理。std::priority_queue
:
- std::vector
通常是最佳选择; 它呈指数增长(减少内存分配的数量),是一个简单的数据结构,非常快速 - 迭代器可以简单地实现为一个包装器,围绕指针。
- std::deque
可能会更慢,因为它通常是线性增长的(需要更多的内存分配),而且访问比向量更加复杂。
- std::list
不能用作它不提供随机访问。对于基本队列,我会使用std::queue
。它默认是deque
的包装器。如果这对您没有用,请使用更专门的内容。
std::priority_queue
也存在(默认情况下是在vector
上),但由于增加了语义,因此取决于您特定的访问模式的性能观察结果,可能更有可能需要自己编写。
vector
具有存储特性,非常不适合从数据集前面进行删除操作。每次pop_front
都需要大量重排。对于简单队列,请避免使用。
list
可能对于任何高频队列来说都太昂贵,因为按照约定它必须提供您不需要的函数。它可能是用作优先队列的候选项,但我的直觉总是相信STL。
vector
把栈实现为快速插入在末尾,而快速删除也在末尾。如果你想要一个FIFO队列,则使用vector
实现将是错误的选择。
deque
或 list
都提供了常数时间的两端插入。当您想要快速从中间移动元素并且迭代器无论如何都保持有效时,list
对于LRU缓存很好用。当插入和删除都在末尾时,通常会使用deque
。
deque
。我不确定优先队列是否有默认值,但我目前正在使用vector
。 - Richardvector
不能用于queue
,因为它不提供pop_front()
。对于只从容器的后面推入和弹出的priority_queue
来说,它是一个很好的选择(也是默认选择)。 - Mike Seymour