【问题标题】:How to store (and read) large arrays/maps/whatever in Java?如何在 Java 中存储(和读取)大型数组/映射/任何内容?
【发布时间】:2011-03-17 08:53:10
【问题描述】:

谁能帮我解决以下问题? 我需要将我今天拥有的数据永久保存在数组中,以便以后使用这些数据进行计算。我在下面解释一个例子。

1,我生成了一个 long[][],这对于我的计算机 RAM 来说太大了。它是一个接一个地生成的。

2,我从我的 long[][] 计算一些东西并将结果保存在一个 double[][] 中 - 对于我的 RAM 来说也太大了。我不需要同时使用整个 long[][],因为在计算中同时使用了一小批行,并且每批都填充了 double[][] 中的一行。

3,我需要对double[][]进行排序,在这里做很多其他不重要的事情。

4,我在多次迭代中重复第 2 步和第 3 步(较大,>10000),这意味着我关心访问和排序的速度。

我知道数组的大小,但显然我无法初始化它们,因为它们太大了,也因为它必须由 int 初始化(到目前为止,我只能运行“小”计算)。当然,我可以使用 Maps 等,但我无法让它工作,我不明白我应该使用哪种类型。我以前从未使用过地图/收藏等。在后一种情况下,我可以使用数组中的一列作为键,因为它们是相同的(类型除外)。键可能只是行号(表示为 long)。

最好不要使用需要安装服务器的数据库来解决这个问题,因为我的程序将被我以外的其他人使用。

我非常感谢任何帮助和建议!

【问题讨论】:

    标签: java arrays serialization map persistence


    【解决方案1】:

    如果数组大于您计算机 RAM 中的存储容量,那么显然您应该将数组的一部分或全部存储在磁盘上。

    为此,您可以使用数据库。现在您不想安装服务器,您可以使用嵌入式数据库,例如 HSQLDB。您可以将 HSQLDB 配置为在应用程序终止时删除所有数据或保留它们以供将来使用。

    另一种方法是使用自定义 Map 实现,只要数据大小增加超过您定义的阈值,就会将数据刷新到辅助存储。为此,可以使用多种策略:FIFO、LIFO、LRU 等。此外,当您需要访问映射的某个元素时,您可以再次从磁盘加载大量相邻元素(或者再次使用一种策略,即更适合您的用例)以减少过多的磁盘 I/O。

    【讨论】:

    • 太棒了!我将测试替代方案,看看哪种方法最有效。我猜 HSQLDB 是最简单的。非常感谢!
    【解决方案2】:

    要存储这些数据,您可以使用netcdfhdf5。您可以获取和保存数组的子集。

    【讨论】:

    • 感谢您的建议!他们俩看起来都很有前途。
    【解决方案3】:

    管理数据子集可能是最佳解决方案。

    但是,您应该问问自己是否使用了正确的机器来完成这项工作。您可以花 225 英镑购买新的 PC,Core 2 Duo 2.5 GHz,4 Gb 内存。您可以花 380 英镑购买 8 GB 的四核 AMD。您可以花 320 英镑购买 16 GB 内存。

    我的观点是,你的时间是有价值的,你需要权衡现在和将来花费多少工作来节省一些内存以及这些内存的价值。

    【讨论】:

    • 嗯...是的,计算机很便宜,尤其是如果您(像我一样)只能接受“松散”的主板、一堆电缆和 Linux。尽管如此,人们总是想做更多、更多……就我而言,我可以用我的电脑测试一些小东西,但是一旦我想分析更多有趣的东西,RAM 就不够了。
    • 在这种情况下,您需要创建一个看起来像数组的类,而是管理“数组”实际上在内存中的多少。基本上你需要一个智能的 long get(int x, int y) 方法。你有多少内存只是一个缓存问题。实现这一点的一种方法是使用内存映射文件。如果你这样做,你的数据大小会受到磁盘空间的限制,这比内存便宜得多(但没有那么快!)
    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2021-11-25
    • 2021-12-04
    相关资源
    最近更新 更多