【问题标题】:vector memory allocation strategy向量内存分配策略
【发布时间】:2012-07-18 15:23:38
【问题描述】:

我写了一小段代码来确定向量中的内存分配是如何完成的。

#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  vector<unsigned int> myvector;
  unsigned int capacity = myvector.capacity();

  for(unsigned int i = 0; i <  100000; ++i) {
    myvector.push_back(i);
    if(capacity != myvector.capacity())
    {
      capacity = myvector.capacity();
      cout << myvector.capacity() << endl;
    }
  }
  return 0;
}

我在 Ubuntu 上使用 Visual Studio 2008 和 g++ 4.5.2 进行了编译,得到了以下结果:

Visual Studio:

1 2 3 4 6 9 13 19 28 42 63 94 141 211 316 474 711 1066 1599 2398 3597 5395 8092 12138 18207 27310 40965 61447 92170 138255

capacity = capacity * 1.5;

g++:

1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072

capacity = capacity * 2;

如您所见,这是两个截然不同的结果。 为什么会这样?是只依赖编译器还是依赖其他因素?

即使对于大量元素,继续将容量翻倍真的有意义吗?

【问题讨论】:

  • 只要符合标准对矢量的要求和效率,就可以随意增加。
  • 我认为容量扩展取决于编译器的实现。我怀疑标准对此有任何说明。
  • 拉伸向量大小,如容量 = 容量 * 1.5;从数学上讲,使用 MSVS 编译器会产生奇怪的结果。 1→2:1 * 1.5 = 1.5,四舍五入为 2 - 很好 3→4:3 * 1,5 = 4.5,但新分配是 4,而不是 5,根据数学中四舍五入 0.5 秒的假设.有人知道,这里发生了什么吗?
  • 他们必须使用半偶数舍入模式en.wikipedia.org/wiki/Rounding#Round_half_to_even

标签: c++ memory-management vector


【解决方案1】:

vector 的增长方式由实现定义。所以在插入相同数量的元素后可以使用不同的策略导致不同的容量

如果您需要依赖分配的项目数量,您应该使用 reserve 和/或 vectorresize 方法

【讨论】:

    【解决方案2】:

    正如你所看到的,VS 用更小的块添加额外的空间,而 G++ 我是通过 2 的幂来实现的。这只是相同基本思想的实现:添加的元素越多,分配的空间就越多下一次(因为您更有可能添加其他数据)。

    假设您向向量添加了 1 个元素,而我添加了 1000 个。很有可能会再添加 1000 个元素,而您不太可能会添加。这就是这种空间分配策略的原因。

    确切的数字肯定取决于某些东西,但这是编译器制造商的推理,因为他们可以以任何他们想要的方式实现它。

    【讨论】:

      【解决方案3】:

      标准只定义了向量的行为。内部真正发生的事情取决于实现。 将容量加倍会导致推/弹出 n 个元素的摊销 O(n) 成本,我猜这是向量所必需的。 更多详情请关注here

      【讨论】:

      • O(n) 的要求是一个重要方面,我之前没有考虑过
      • 错了。 “任何大于 1 的因子确保 O(1) 摊销附加复杂性趋向无穷”github.com/facebook/folly/blob/master/folly/docs/FBVector.md
      • 添加/删除一个元素是在(摊销)O(1)中完成的,真的。添加/删除 n 个元素 - 如我的回答所述 - 是在线性时间内完成的(意思是:插入双倍数量的元素需要两倍的时间)。但我承认我的回答有点混乱。当我重新阅读我的答案时,我想知道自己,我在想什么;)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 2018-08-23
      • 1970-01-01
      • 2015-10-09
      相关资源
      最近更新 更多