使用 std::vector 的指数内存消耗增长

Posted

技术标签:

【中文标题】使用 std::vector 的指数内存消耗增长【英文标题】:Exponential memory consumption growth using std::vector 【发布时间】:2014-12-01 07:57:19 【问题描述】:

我正在开发一个需要提高内存效率的程序。我在我的程序中使用了std::vector 来存储大量元素。但是,我注意到,当较大元素数量时,程序的内存大小会呈指数级增长。 比如我写了如下代码:

#include <iostream>
#include <vector>
using namespace std;

int main()
    int vecSize;
    cin >> vecSize;
    vector<double> a(vecSize);
    return 0;

然后我使用 gnu time 命令监控内存消耗,如下所示:

/usr/bin/time -f "Mem: %M" a.out

这是我得到的不同向量大小的内存结果:

VecSize       MemUsage
10:           4720 KB
100:          4720 KB
1000:         4736 KB
10000:        5024 KB
100000:       7744 KB
1000000:      35872 KB
10000000:     317120 KB

有人知道为什么当元素数量超过100000时,内存用量快速增长?

【问题讨论】:

***.com/questions/11560904/… 调试构建,是否有机会? 【参考方案1】:

MSalters 是对的,我看不懂!

答案很简单。对我来说,增长似乎是线性的。

您选择了呈指数增长的 VecSize。您应该期望 MemUsage 也呈指数级增长! (在大 n 限制中 - 可能存在小尺寸优化,小 n 的近乎恒定使用证明了这一点......)

出于好奇,我对数据进行了线性回归,相关系数为 1.0——表明 VecSize 和 MemUsage 之间的关系(如发布的那样)是(很可能......不要杀了我统计学家)线性.

【讨论】:

+1 1. 更快 2. 应用形式化分析方法:-) 顺便说一句,分配器开销几乎是 4 倍。可能会为那里的其他请求留出一个池...... “正式”哈!只要没有来自 stats.stackexchange.com 的人出现,这是正式的 :) "我不同意 MSalters——我相信答案要简单得多。对我来说,增长似乎是线性的。" 这正是 MSalters 所说的——“您只需初始化一个大小呈指数增长的向量。它的大小在请求的父系中是线性的。“您似乎对此感到困惑的部分(“运行时增长必须是指数级”)对于不断增长的向量来说是完全正确的。 @ildjarn 谢谢,阅读理解很难!他一直都是对的。抱歉,@MSalters 很粗鲁!但是,我认为 MSalters 误解了提问者的误解(以获得一点元数据)。提问者期望看到线性增长,因为他做出(不知不觉 - 我的假设!)指数增长 vecsize。【参考方案2】:

运行时增长必须是指数级的,push_back 的摊销时间为 O(1)。如果一次增长一个元素,增长 100.000 个元素的向量将需要 100.000 个元素副本。

但是,在这种情况下,向量根本不会增长。您只需初始化一个大小呈指数增长的向量。它的大小在请求的父亲中是线性的。这并不奇怪。

【讨论】:

【参考方案3】:

我看不到数字有任何指数增长。大小从 10^5 变为 10^6 (10x) 会增加大约 5 倍的内存消耗。从 10^6 到 10^7 (10x) 会增加大约 10 倍的内存消耗。所以它是线性的。

前几个数字(小的向量大小)在这里没有什么作用——向量使用的内存可能主要由程序及其运行时的其他需求决定。一旦超过了这一点并且向量大小开始占主导地位,您就会得到大致线性缩放,所以一切都很好。

【讨论】:

支持第二段,我认为这是相关的答案。

以上是关于使用 std::vector 的指数内存消耗增长的主要内容,如果未能解决你的问题,请参考以下文章

C++ 动态分配的 std::vector

docker devicemapper 数据文件大小呈指数增长并消耗我的主机磁盘 90%

如何将 std::vector 的容量限制为元素的数量

std::vector 的容量如何自动增长?费率是多少?

改变向量内存分配策略?

使用 std::vector 和内存释放