为什么 std::queue 使用 std::dequeue 作为底层默认容器?
Why does std::queue use std::dequeue as underlying default container?
如上文所述cplusplus.com,std::queue
实现如下:
queues are implemented as containers adaptors, which are classes that
use an encapsulated object of a specific container class as its
underlying container, providing a specific set of member functions to
access its elements. Elements are pushed into the "back" of the
specific container and popped from its "front".
The underlying container may be one of the standard container class
template or some other specifically designed container class. This
underlying container shall support at least the following operations:
......
The standard container classes deque and list fulfill these
requirements. By default, if no container class is specified for a
particular queue class instantiation, the standard container deque is
used.
我很困惑为什么在这里默认使用 deque(类固醇的双端队列)而不是 list(这是一个双向链表)。
在我看来,std::deque
太过分了:它是一个双端队列,但也具有常量时间元素访问和许多其他特性;基本上是一个功能齐全的 std::vector 禁止 'elements are stored contiguously in memory' 保证。
由于正常的 std::queue
只有很少的可能操作,在我看来,双向链表应该更有效,因为内部需要进行的管道要少得多。
为什么 std::queue
默认使用 std::deque
而不是 std::list
来实现?
原因是双端队列比列表快几个数量级。 List 单独分配每个元素,而 deque 分配大块元素。
list的优点是可以删除中间的元素,而队列不需要这个特性
别再把 list
想成 "This is awkward to use, and lacks a bunch of useful features, so it must be the best choice when I don't need those features"。
list
被实现为一个带有缓存计数的双向链表。在少数情况下它是最佳的;当您需要非常非常强大的 reference/pointer/iterator 稳定性时。当您在容器中间擦除和插入的次数比迭代到容器中间的次数多几个数量级。
仅此而已。
通常实现了std
数据类型,然后分析了它们的性能和其他特性,然后编写了标准说"you gotta guarantee these requirements"。还剩下一点回旋余地。
所以当他们写 queue
时,可能有人分析了 list
和 deque
的执行情况并发现 deque
的速度有多快,所以使用了 deque
默认情况下。
在实践中,有人可以发布一个性能糟糕的 deque
(例如,MSVC 的块大小很小),但是让它比 std::list
所需的更糟将是棘手的. list
基本上要求每个元素一个节点,这让内存缓存哭泣。
如上文所述cplusplus.com,std::queue
实现如下:
queues are implemented as containers adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container, providing a specific set of member functions to access its elements. Elements are pushed into the "back" of the specific container and popped from its "front".
The underlying container may be one of the standard container class template or some other specifically designed container class. This underlying container shall support at least the following operations:
......
The standard container classes deque and list fulfill these requirements. By default, if no container class is specified for a particular queue class instantiation, the standard container deque is used.
我很困惑为什么在这里默认使用 deque(类固醇的双端队列)而不是 list(这是一个双向链表)。
在我看来,std::deque
太过分了:它是一个双端队列,但也具有常量时间元素访问和许多其他特性;基本上是一个功能齐全的 std::vector 禁止 'elements are stored contiguously in memory' 保证。
由于正常的 std::queue
只有很少的可能操作,在我看来,双向链表应该更有效,因为内部需要进行的管道要少得多。
为什么 std::queue
默认使用 std::deque
而不是 std::list
来实现?
原因是双端队列比列表快几个数量级。 List 单独分配每个元素,而 deque 分配大块元素。
list的优点是可以删除中间的元素,而队列不需要这个特性
别再把 list
想成 "This is awkward to use, and lacks a bunch of useful features, so it must be the best choice when I don't need those features"。
list
被实现为一个带有缓存计数的双向链表。在少数情况下它是最佳的;当您需要非常非常强大的 reference/pointer/iterator 稳定性时。当您在容器中间擦除和插入的次数比迭代到容器中间的次数多几个数量级。
仅此而已。
通常实现了std
数据类型,然后分析了它们的性能和其他特性,然后编写了标准说"you gotta guarantee these requirements"。还剩下一点回旋余地。
所以当他们写 queue
时,可能有人分析了 list
和 deque
的执行情况并发现 deque
的速度有多快,所以使用了 deque
默认情况下。
在实践中,有人可以发布一个性能糟糕的 deque
(例如,MSVC 的块大小很小),但是让它比 std::list
所需的更糟将是棘手的. list
基本上要求每个元素一个节点,这让内存缓存哭泣。