关于deque <t>的额外间接</t>

时间:2011-11-29 03:31:31

标签: c++ visual-c++ vector deque arraydeque

想知道为什么我的内存访问速度比我预期的慢一些,我终于发现deque的Visual C ++实现确实有一个内置的间接额外层,摧毁了我的记忆地点。<​​/ p>

即。它似乎包含T*的数组,而不是T的数组。

我可以在VC ++中使用另一个没有这个“功能”的实现,还是有某种方法(虽然我认为不太可能)在这个实现中能够避免它?

我基本上正在寻找一个前面也有O(1)推/弹的vector
我想我可以自己实现它,但是处理allocator等等是很痛苦的,需要一段时间才能做到正确,所以我宁愿使用之前编写/测试过的东西。

3 个答案:

答案 0 :(得分:10)

无论出于何种原因,至少从MSVC 2010开始,std::deque实现似乎使用了一个令人难以置信的小块大小(如果我没弄错的话,最多16个字节或1个单个元素!)。

根据我的经验,这可能会导致非常严重的性能问题,因为数据结构中的每个“块”基本上只会存储单个元素,从而导致各种额外开销(时间和内存)。 / p>

我不知道为什么这样做。据我了解,设置deque具有如此小的块大小正是它应该如何完成。

查看gcc stdlib实施。从内存中他们使用更大的块大小。

编辑:试图解决其他问题:

  • std::deque 应该有一个额外的间接层。它通常被实现为“被阻止的”数据结构 - 即存储“节点”的数组,其中每个节点本身是数据元素的数组。它不像链接列表 - 节点数组永远不会像列表那样“遍历”,它总是直接编入索引(即使每个块有1个元素)。

  • 当然,您可以滚动自己的数据结构,在前面留出一些额外的空间。它不会有最坏的O(1) push/pop front/back行为,因此它不会满足std::deque容器的要求。但如果你不关心任何......

答案 1 :(得分:2)

C ++标准不允许std::deque在向前或向后推送时重新分配。这些操作始终是恒定的时间。不摊销始终

C ++标准没有这样的容器。根据我的知识,Boost没有一个(想到Boost.Container库可能;我没有考虑过它。)

答案 2 :(得分:0)

您抱怨的间接实际上是强制标准要求,引用/指针永远不会被push / pop front / {{1 (显然除了那些引用/指向被删除元素的指针)。

所以你看到这个要求与任何复杂性要求无关。

当没有可用空间时,此间接还允许更快(但仍为O(大小))back push / front