【问题标题】:Memory efficient data structure for numbers数字的内存高效数据结构
【发布时间】:2013-04-26 13:06:01
【问题描述】:

我有一张很大的桌子:

id1 id2 count
1   234   4
1    5    123
1   432   5
23  234   7

id1 和 id2 有许多不同的值。 count 的数值有限(1-30000 或其他),我知道它们中的大多数都等于 1。

当我将这张表存储在 .net 字典中时,它需要大约 10gb 的内存。 我想找到内存高效的数据结构来存储这些数据。

完美的哈希可能是理想的解决方案,但问题是冲突。我可以获得表中不存在的 id 的值。也许 DAWG 可以提供帮助?还是别的什么?


数据结构的主要用途是通过id1和id2进行计数。

【问题讨论】:

    标签: algorithm data-structures memory-efficient


    【解决方案1】:

    如果几乎​​所有的计数都是 1,那么您可以使用两种数据结构:一个包含所有计数为 1 的 id 对的 HashSet,以及一个用于计数大于 1 的 id 对的字典。这使得递增和检查计数有点慢,但它应该节省一些空间。 (我不知道 .Net 数据结构在内部是如何布局的,所以我不敢猜测,但如果是 C++,我会说它会减少 25-30% 的空间消耗,具体取决于值“几乎所有”。)

    如果这还不够节省空间,下面是一些可能性的概述,尽管可能需要大量工作才能获得不确定的收益:

    一般来说,容器数据结构的成本由元素的数据大小加上一些每个元素的开销,再加上一些每个数据结构的开销组成。哈希表具有中等数量的每个元素开销(一个链接到桶中的下一个元素,加上分配/对齐开销);并且二叉树有很多每个元素的开销(两个或更多通常三个链接,加上分配/对齐开销)。从技术上讲,向量没有每个元素的开销,但它们通常被过度分配以减少插入时间,因此您应该将它们视为每个元素的开销为 50-100%。

    一个结果是,如果您想出一种减少元素数量的方法,您通常可以节省空间。例如,您可以使用 id-pairs 的 HashSet,正如我上面建议的那样。但是,如果单个 id1 值比对少得多——即,如果 id 重复——那么您可以将其替换为将 id1 映射到 id2 向量的字典,这可能会减少开销。这样做有一个很大的缺点:它使查找和插入变得更加昂贵;此外,只有当哈希表每个元素的开销大于预期的向量过度分配开销时,它才会有所帮助。

    【讨论】:

      【解决方案2】:

      您对 id1 和 id2 是否有一个相当小的上限?如果是这样,那么您可以将它们存储为一个数字;例如,如果两个数字的上限均为 255,则可以将它们存储为 id = id1 + id2 * 256;如果需要,您可以提取 id1 = id % 256 和 id2 = id / 256(使用整数除法)

      现在每个 id 对都有一个索引,并且由于大多数计数为 1,因此您可以将其存储为 sparse array(通常稀疏数组的“空”值是 0 或 null,在你的情况是 1)

      如果没有将两个 id 组合成一个索引的好方法,那么您可以将其存储为 sparse matrix,其中 id1 作为 x 值,id2 作为 y 值(反之亦然)

      【讨论】:

      • 没有上限,我认为稀疏矩阵不是存储的好方法,因为 id1 和 id2 不是矩阵的索引。 id1 和 id2 的某些组合可能不存在于表中。(1 和 2 存在,1 和 3 不存在,1 和 4 存在)
      猜你喜欢
      • 1970-01-01
      • 2013-05-20
      • 2020-08-22
      • 2015-06-26
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多