ocaml极其庞大的数据结构建议

时间:2012-04-23 05:07:57

标签: list data-structures ocaml large-data

我正在寻找有关哪种数据结构可用于OCaml中可扩展的超大型结构的建议。

如果有足够的内存,我不希望堆栈溢出或指数堆增长。所以这几乎消除了标准的lib的List.map函数。速度不是一个问题。

但对于初学者来说,让我们假设我在2 ^ 10 - 2 ^ 100项目的范围内运作。

我对结构只执行了三次“操作”:

(1)结构子集上的映射函数,它可以增加或减少结构

(2)扫描结构

(3)删除结构中满足特定标准的特定项目对

最初我使用的是常规列表,这仍然是非常需要的,因为结构在不断变化。通常在执行所有操作之后,结构最多可以加倍(或者某些东西),或者减少到空列表[]。也许从一开始就让我倍增,但这是不可避免的。

无论如何,大约2 ^ 15 --- 2 ^ 40项开始引起严重问题(可能是由于我使用的天真列表功能)。该程序使用100%的cpu,但几乎没有内存,通常在一两天之后堆栈溢出。

如果可能,我宁愿开始使用更多内存,以便继续在更大的空间内操作。

无论如何,如果有人有任何建议,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果你有足够的空间,理论上要包含数据结构的所有项目,你应该查看具有有效内存表示的数据结构,尽可能少的bookeeping。动态数组(当你需要更多空间时以指数方式调整大小)比list更有效地存储(用一个完整的单词来存储每个单元格的尾部),所以你得到的内存大约是同一内存使用量的两倍。

如果您无法将所有元素保存在内存中(这就是您的数字的样子),您应该寻求更抽象的表示。没有关于你的元素是什么的更多信息,很难说出更多信息。但也许一个抽象表示的例子可以帮助你设计你需要的东西。

想象一下,我想记录一组整数。我想制作工会,这些集合的交叉点,以及一些更加时髦的操作,例如“获取多个所有元素”。我希望能够为非常大的集合(数以万计的不同整数)做到这一点,然后我希望能够在我构建的这个集合中选择一个元素,任何一个元素。我可以做的是存储与这些集合的定义相对应的逻辑公式,而不是尝试存储整数,整数集或布尔数组的列表:一组整数P由公式表征FF(n) ⇔ n∈P。因此,我可以定义一种预测(条件):

type predicate =
  | Segment of int * int   (* n ∈ [a;b] *)
  | Inter of predicate * predicate
  | Union of predicate * predicate
  | Multiple of int  (* n mod a = 0 *)

存储这些公式需要很少的内存(与我想要总共应用的操作数成比例)。建立交叉点或联合需要恒定的时间。然后我会做一些工作来找到满足公式的元素;基本上我不得不推理这些公式的含义,从中得到一个正常的形式(它们都是“满足某些模数标准的区间有限联合的元素”),并从那里提取一些元素。

在一般情况下,当您在数据集上获得“命令”时,“在此子集上添加映射结果”,您可以始终而不是实际评估此命令,而是将其存储为数据 - 你的结构的定义。您可以更准确地描述这些命令(例如,您说“地图”,但存储(elem - > elem)函数将不允许您轻松地对结果进行推理,也许您可​​以将该映射操作表示为具体组合对于操作而言,您可以更精确地在这个抽象层面上处理它们,而无需实际计算元素。