C ++程序中的内存使用情况

时间:2014-07-18 09:04:50

标签: c++ memory vector boost-unordered

我编写了一个程序,需要使用以下库处理非常大的数据:

  • 矢量
  • 升压:: unordered_map
  • 升压:: unordered_multimap

所以,我有内存问题(该程序使用很多),我想也许我可以替换这些库(已经存在的东西或我自己的实现):

所以,有三个问题:

  • 如果我用C数组替换vector,我会节省多少内存?值得吗?
  • 有人可以解释当前实现中boost :: unordered_map和boost :: unordered_multimap中使用的内存是怎样的?就像存储它们以实现它们的性能一样。
  • 你能否推荐一些在内存使用方面优于boost :: unordered_map和boost :: unordered_multimap的库(但不是太慢)?

5 个答案:

答案 0 :(得分:5)

std::vector具有内存效率。我不了解提升地图,但是Boost人通常知道他们正在做什么,我怀疑你是否会通过创建自己的变体来节省大量内存。

您可以做一些其他事情来帮助解决内存问题:

  1. 以64位编译。在64位进程中耗尽内存非常很难。
  2. 你的内存不足,但内存可能会被换掉。您应该看看是否需要立即将所有内容加载到内存中,也许您可​​以一次处理数据块。
  3. 作为附带好处,一次处理一大块数据可以让您并行运行代码。
  4. 由于内存现在如此便宜,所以分配10GB的RAM非常简单,我想你的瓶颈将在于处理你的数据,而不是分配数据。

答案 1 :(得分:1)

这两篇文章解释了无序关联容器的一些常见实现的数据结构:

即使实现之间存在一些差异,它们也是适度的 - 每个元素最多只有一个字。如果你使用最小开销解决方案,例如排序向量,这将使每个元素获得2-3个字,如果你的对象很大,甚至不会提高2倍。所以,你最好不要使用更多内存或通过使用数据库等方式彻底改变你的方法。

答案 2 :(得分:0)

std :: vector基本上是一个连续的数组,加上几个字节的开销。关于使用矢量改进的唯一方法是使用较小的元素类型。你可以存储一个短的int而不是一个常规的int吗?如果是这样,你可以将向量内存减少一半。

您是否可能使用这些容器来保存指向堆上许多对象的指针?如果是这样,您可能会在堆中浪费大量空间,可以通过编写自定义分配器,或者通过完全取消指向堆元素的指针,以及在容器中存储值类型来保存。

查看您的班级类型。考虑所有指针类型,以及它们是否需要是动态存储。典型的类通常具有挂在基础对象上的指针成员,这意味着单个对象本身就是内存块的图形。你可以越多地内联你的类成员,你对堆的使用效率就越高。

RAM在2014年很便宜。如果您当前的盒子没有为项目切割它,那么很容易构建具有64-256GB RAM和固态硬盘的x86-64英特尔盒子作为快速交换。希望这不是我们正在讨论的商业桌面应用程序。 :)

答案 3 :(得分:0)

如果您只有一组数据和多种访问方式,可以尝试使用boost::multi_index这里是documentation

答案 4 :(得分:0)

我最后更改了boost::unordered_multimap std::unordered_map vector的{​​{1}}。

boost::unordered_multimap消耗的std::unordered_map vector消耗的内存的两倍以上是由于它保留的额外指针(每个元素至少有一个额外的指针)以及它存储的事实key和每个元素的值,而unordered_map的{​​{1}}仅为包含所有碰撞元素的向量存储一次键。

在我的特定情况下,我试图存储大约4,000万个整数,在理想情况下消耗大约15 GB的内存。使用multimap我使用的地图消耗超过40 GB,我使用大约15 GB(更多因为指针和其他结构,但它们的大小,如果卑鄙)。