大型2D数组数据的数据结构

时间:2018-06-22 18:34:02

标签: data-structures language-agnostic

我与一个模拟一起工作,该模拟输出一个2D数据数组,其中每一列是一个不同的模拟变量(大约50,000个变量),每一行都是每个时间样本(可变,但通常是10,000个或更多时间点)。

需要以两种不同的方式访问此数据:要么获取少量变量的整个时间序列,要么获取特定时间点的每个变量。换句话说,有时候我需要从数据中读取列,有时候我需要读取行。

当前,模拟以大行顺序输出二进制格式。这样可以轻松获取特定时间的每个变量,但是读取单个变量的整个时间序列非常慢,因为数据分散在整个千兆字节的文件中。

是否存在某种可以帮助我的数据结构?我知道我可以有效地使文件大小增加一倍,并以行大和列大的顺序存储数据,但是文件已经很大。

我在这里还浏览了其他一些问题,但是似乎没有一个问题可以解决这个特殊的用例。

1 个答案:

答案 0 :(得分:0)

仅免责声明-我不建议在您的程序中实现此数据结构。在行访问上浪费的时间比在列访问上节省的时间更多。但是,这似乎是您唯一的选择,如果您不能增加内存大小,并且如果您绝对必须改善列访问(例如,满足某个阈值以防止在其他地方拖延),那么这可能是您唯一的选择。

您可以调整2D数组,以使从行读取和从列读取的速度都比以前从列读取的速度快,但是从行读取会大大降低性能。这确实也意味着对特定位置建立索引会比较慢,但是缓存未命中的影响可能更大。

为简单起见,假设矩阵的大小为NxN,并且N是一个完美的正方形。现在,我们可以将原始矩阵的第i行排列在每个i + k * sqrt(N)元素的1D矩阵上。第j列将在行之间的这些拉伸之间(并相交)成批sqrt(N)出现。类似于floor(index / sqrt(N)) * N + index mod sqrt(N)

这完成的是每N个元素,您现在具有用于各个行和列的sqrt(N)元素,而不是N个行元素,而只有1个列元素。现在,当您拉入缓存行时,无论您遍历行还是列,而不是冒“全有或全无”的风险,现在每个元素都会有多个(至少有几个缓存命中)。这是否是一个好的折衷方案,取决于您需要提高最差情况性能的迫切性以及对最佳情况性能的关注程度。

要将现有的2D数组转换为这种形式,可以获取构成矩阵下半部分的行,并将其列与各自的上半行交错。然后取该细长矩阵的右半部分,并将其行与左半部分的行交织。重复sqrt(N)次。请注意,这太慢了,我不建议您使用它来转换数据库,我只是将其作为理解数据结构的另一种方式提供。要转换数据库,我需要计算公式,然后逐个移动每个元素。