constexpr 数组与双端队列,内存利用率

Posted

技术标签:

【中文标题】constexpr 数组与双端队列,内存利用率【英文标题】:constexpr array vs deque, memory utilization 【发布时间】:2021-12-28 05:31:53 【问题描述】:

我需要在我的代码中存储大约 30 个整数的预先已知大小,我已经准备好了

constexpr std::array<size_t, 30> MAPPING1, 2, 3, ...;

如果我没记错的话,上面会在编译时进行评估,但它也会占用一个大小为 30 个整数的单个顺序内存块?

如果是这样,是否值得使用 std::deque 代替

const std::deque<int> MAPPING1, 2, 3, ...;

这样,对于双端队列,我们​​不会使用单个大的顺序内存块,而是使用一堆碎片块,因此即使内存碎片也能正常工作?

如果我遗漏了什么,请告诉我,谢谢

【问题讨论】:

数组总是一个连续的内存块。它是固定大小的(即它的大小在编译时已知)双端队列是一个动态容器,它可以在运行时增大大小。 Deque 对其内容使用动态分配(每个项目都分配在不同的位置),而如果您不自己在动态存储上分配它,则数组不会。 如果您已经知道大小,为什么还要考虑出队? IMO 碎片对于如此小的分配是不值得担心的。使用array。此外,deque 将使用更多内存,因为它需要记账。 【参考方案1】:

这里不值得使用std::deque

它还会占用一个大小为 30 个整数的连续内存块吗?


是的,它会占用一个大小为 30 个整数的连续内存块在堆栈中

这样,对于双端队列,我们​​不会使用单个大的顺序内存块,它可能会使用一堆碎片块,因此即使内存是碎片的,它也能正常工作?


它是implementation-dependent,对于 30 个整数,它们可能会被分成几个小块,也可能不会,但它会使用 内存,因此会产生运行时开销:

与 std::vector 不同,双端队列的元素不被存储 连续的:典型的实现使用一个单独的序列 分配的固定大小的数组,带有额外的簿记,这意味着 对双端队列的索引访问必须执行两个指针解引用, 与向量的索引访问相比,它只执行一次。

根据@Homer512的评论,我们在使用堆的时候还需要注意内存碎片,可能存在内存浪费,我们无法避免。

【讨论】:

好答案。我没有检查过 VC,但 gcc 使用 512 字节的固定块作为其双端队列。或 128 个整数。也许值得注意。我还要补充一点,现在堆碎片问题比历史上要少得多。尤其是在 64 位中,这不值得担心 @Homer512 感谢您提供如此出色的补充!我想参考您的评论。 感谢您的回答和澄清,我现在明白了:-)

以上是关于constexpr 数组与双端队列,内存利用率的主要内容,如果未能解决你的问题,请参考以下文章

双端队列deque的应用

双端队列-deque集vector与list于一身的牺牲内存换功能完善

std::deque双端队列介绍

python:双端队列与列表性能比较

每日一题641. 设计循环双端队列

HDU6375双端队列