【问题标题】:Reading / writing lots of int[] (BitSet) data into file(s) repeatedly can be done fast in Java?在 Java 中可以快速地重复读取/写入大量 int[] (BitSet) 数据到文件中吗?
【发布时间】:2013-04-09 23:45:04
【问题描述】:

我的主程序如下(伪代码):

public void main(String[] args) {

    // produce lots of int[] data which is stored inside a list of hashmaps
    List<HashMap<Integer, int[]>> dataArray1 = new
                                    ArrayList<HashMap<Integer, int[]>>();
    ...

    // create a new list of data, similar to dataArray1
    // now we will write into dataArray2 and read from dataArray1
    List<HashMap<Integer, int[]>> dataArray2 = new
                                    ArrayList<HashMap<Integer, int[]>>();
    while (true) {
        if (exitCondition) break;
        ...
        for index1, index2 in a set of indices {
            int[] a1 = dataArray1.get(index1).get(key1);
            int[] a2 = dataArray1.get(index2).get(key2);
            int[] b = intersect a1 and a2;
            int i = generateIndex(index1, index2);
            int key = generateKey(key1, key2);
            dataArray2.get(i).put(key, b);
        }
    }

    // now we can remove dataArray1
    dataArray1 = null;

    // create a new list of data, similar to dataArray2
    // now we will write into dataArray3 and read from dataArray2
    List<HashMap<Integer, int[]>> dataArray3 = new
                                    ArrayList<HashMap<Integer, int[]>>();
    while (true) {
        if (exitCondition) break;
        ...
        for index1, index2 in a set of indices {
            int[] a1 = dataArray2.get(index1).get(key1);
            int[] a2 = dataArray2.get(index2).get(key2);
            int[] b = intersect a1 and a2;
            int i = generateIndex(index1, index2);
            int key = generateKey(key1, key2);
            dataArray3.get(i).put(key, b);
        }
    }

    // now we can remove dataArray2
    dataArray2 = null;

    ...
    // and so on 20 times

}

我的问题是,在某些时候dataArrayk 对于某些k &gt; 1 变得很重(比如 20 Gb),因此不可能将其存储在内存中。我可以将int[] 更改为BitSet 但这无济于事,内存消耗更多。

解决方案是使用数据库或文件系统。你会推荐使用什么?我需要性能(时间执行),内存无所谓。如果您的经验是数据库,那么请推荐用于处理特定(哪个?)数据库的最快接口,无论是 bd4 (Berkeley db)、postgresql 还是其他。如果是文件系统,请推荐最快的接口(文件库)。

关于读写统计: 在我的代码的每个 while 循环中,我执行的读取次数比写入次数多 3 倍,例如:对于一级 k,我从 dataArray_k 读取 12000 次并写入 dataArray_(k+1) 4000 次。

我可以将来自List&lt;HashMap&lt;Integer, int[]&gt;&gt; dataArray1 的每个哈希图存储在单独的文件中。

【问题讨论】:

  • 告诉我们 yoi 想要做什么会更有意义。 20GB 的数据很多
  • 简单的答案 - 我有一百万个代表生物细胞传感器数据的数组,我需要以某种方式相交,所以在每个 dataArrayk 中,我存储了从以前的dataArray_k-1。我的程序已经过优化,所以不会占用这么多内存。
  • 它取决于您的生物算法,如果计算仅参考附近的值,则磁盘方法将起作用。如果计算总是访问所有值,最好购买更多内存,同时进行优化,例如短数组。
  • 你的生物数据可以被认为是二维的吗?还是 3 维?
  • 我觉得基于磁盘的存储具有巨大的缓存是有道理的。那么数据的访问路径是什么?这对性能有多重要?特定数据块的请求是否比其他数据块更频繁?您需要事务管理吗?显示的伪代码是您在该应用程序中对数据执行的唯一操作吗?在启动数据库和设计模式等之前,我会考虑一种基于文件的方法,它具有智能数据结构和某种基于内存的缓冲/缓存/预读机制。

标签: java database performance memory filesystems


【解决方案1】:

昨天我对不同 java io/nio 技术的读取性能进行了评估。 事实证明,在PC上java.nioIntBuffer提供的Memory Map的读取性能最好。 详细代码在这里:Fastest way to read huge number of int from binary file

当然,事实证明,算法更改更有可能提高速度。例如,在您的情况下,请考虑使用四叉树或 R* 树等多维搜索结构,以减少对密切相关的生物数据的磁盘访问。

更新:当我现在看到您的代码时,您似乎总是遍历所有值(这不是很清楚)。首先尝试使用一个短数组,它需要一半的空间。

【讨论】:

  • @TheBlastOne 如果你写了 +1,别忘了点击箭头按钮 ;-)
  • 一毫秒,我想评论“downvoter!!! 你真丢脸”,但是是 no click no upvote.....doh...
  • +1 我编写了一个库,以便更轻松地处理内存映射文件。包括在进程之间共享它们。它可以处理 TB 中的数据而无需使用太多堆 (github.com/peter-lawrey/Java-Chronicle BTW 使用 longs 可能比使用 ints 更快。
【解决方案2】:

老实说,用 Java 读取这么多数据可能会是一场噩梦。我只处理了多达 5 GB 的文本文件,这真的很慢而且很困难。您可以使用更接近操作系统的东西(sed、grep、find 等)。如果 Java 是必须,那么我认为 NIO 包会比简单的文件更快

Look here

【讨论】:

    猜你喜欢
    • 2013-10-28
    • 2011-08-31
    • 2010-10-02
    • 1970-01-01
    • 2010-11-25
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多