关于德克<T>的额外间接寻址

About deque<T>'s extra indirection

本文关键字:gt 间接寻址 lt 于德克 德克      更新时间:2023-10-16

想知道为什么我的内存访问比我预期的要慢,我最终发现deque的visualc++实现确实有一个额外的内建层,破坏了我的内存局部性。

。它似乎保存的是T*数组,而不是T数组。

是否有另一个实现,我可以使用vc++,没有这个"功能",或者有一些方法(虽然我认为它不太可能)能够避免它在这个实现?

我基本上是在寻找一个在前面也有O(1) push/pop的vector
我想我可以实现它自己,但处理allocator s,这是一个痛苦,它需要一段时间才能得到正确的,所以我宁愿使用以前编写/测试的东西,如果可能的话。

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

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

我不知道为什么这样做。据我所知,设置deque具有如此小的块大小正是而不是应该做的。

查看gcc stdlib实现。从内存中,它们使用更大的块大小。

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

  • std::deque 应该有一个额外的间接层。它通常被实现为一个"阻塞"的数据结构——即存储一个"节点"数组,其中每个节点本身就是一个数据元素数组。它不像链表——节点数组从来没有像链表那样"遍历",它总是直接索引(即使在每个块有一个元素的情况下)。

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

c++标准不允许std::deque在向前或向后推送时进行重新分配。这些操作总是常数时间。非平摊总是

c++标准没有这样的容器。据我所知,Boost没有(Boost想)。容器库可能;

你所抱怨的间接性实际上是强制的,这是push/pop front/back的标准要求,引用/指针永远不会无效(除了那些指向已删除元素的引用/指针,显然)。

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

这个间接也允许更快(但仍然O(size)) push front/back当没有可用的空间