1

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

  • 向量
  • boost::unordered_map
  • boost::unordered_multimap

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

所以,三个问题:

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

5 回答 5

5

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

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

  1. 编译为 64 位。在 64 位进程中耗尽内存非常困难。
  2. 您不会耗尽内存,但内存可能会被换出。相反,您应该查看是否需要一次将所有内容加载到内存中,也许您可​​以一次处理数据块。
  3. 作为附带的好处,一次处理大量数据允许您并行运行代码。

现在内存如此便宜,因此分配 10GB 的 RAM 非常简单,我想您的瓶颈将在于您对数据的处理,而不是分配数据。

于 2014-07-18T09:11:03.383 回答
1

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

尽管实现之间存在一些差异,但它们是适度的——每个元素最多一个单词。如果您使用诸如排序向量之类的最小开销解决方案,这将为每个元素增加 2-3 个单词,如果您的对象很大,则甚至不会提高 2 倍。因此,您可能最好求助于具有更多内存的环境,或者通过使用数据库或其他东西从根本上改变您的方法。

于 2014-07-18T10:29:40.213 回答
0

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

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

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

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

于 2014-07-18T09:22:51.357 回答
0

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

于 2014-07-18T09:26:15.887 回答
0

我最终改变boost::unordered_multimap了 for std::unordered_mapof vector

boost::unordered_multimap由于它保留的额外指针(每个元素至少一个额外的指针)以及它存储每个元素的键和值的事实,消耗的内存是std::unordered_mapof消耗的内存的两倍以上 ,而对于向量只存储一次键包含所有碰撞元素。vectorunordered_mapvector

在我的特殊情况下,我试图存储大约 4000 万个整数,在理想情况下消耗大约 15 GB 的内存。使用 multimap 时,我会消耗超过 40 GB 的空间,而使用我使用大约 15 GB 的地图(由于指针和其他结构的原因会多一点,但它们的大小如果卑鄙的话)。

于 2014-08-07T09:23:13.860 回答