java - 从二进制文件中读取大量 int 的最快方法

标签 java io nio

我在嵌入式 Linux 设备上使用 Java 1.5,并希望读取一个包含 2MB int 值的二进制文件。 (现在是 4bytes Big Endian,但我可以决定格式)

使用DataInputStream通过BufferedInputStream使用dis.readInt()),这50万次调用需要17s来读取,但是文件读入一个大字节缓冲区需要 5 秒。

我怎样才能更快地将文件读入一个巨大的 int[]?

读取过程不应额外使用超过 512 kb。

下面使用 nio 的代码并不比 java io 的 readInt() 方法快。

    // asume I already know that there are now 500 000 int to read:
    int numInts = 500000;
    // here I want the result into
    int[] result = new int[numInts];
    int cnt = 0;

    RandomAccessFile aFile = new RandomAccessFile("filename", "r");
    FileChannel inChannel = aFile.getChannel();

    ByteBuffer buf = ByteBuffer.allocate(512 * 1024);

    int bytesRead = inChannel.read(buf); //read into buffer.

    while (bytesRead != -1) {

      buf.flip();  //make buffer ready for get()

      while(buf.hasRemaining() && cnt < numInts){
       // probably slow here since called 500 000 times
          result[cnt] = buf.getInt();
          cnt++;
      }

      buf.clear(); //make buffer ready for writing
      bytesRead = inChannel.read(buf);
    }


    aFile.close();
    inChannel.close();

更新:对答案的评估:

在 PC 上,使用 IntBuffer 方法的内存映射是我设置中最快的。
在嵌入式设备上,如果没有 jit,java.io DataiInputStream.readInt() 会快一点(17 秒,而带有 IntBuffer 的 MemMap 是 20 秒)

最终结论: 通过算法更改更容易实现显着加速。 (初始化文件较小)

最佳答案

我不知道这是否会比 Alexander 提供的更快,但您可以尝试映射文件。

    try (FileInputStream stream = new FileInputStream(filename)) {
        FileChannel inChannel = stream.getChannel();

        ByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
        int[] result = new int[500000];

        buffer.order( ByteOrder.BIG_ENDIAN );
        IntBuffer intBuffer = buffer.asIntBuffer( );
        intBuffer.get(result);
    }

关于java - 从二进制文件中读取大量 int 的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16022053/

相关文章:

java - Hadoop 将数据从映射器减少到组合器

java - Java中用Scanner读取文本文件——Token的返回字符

go - 不能将 (type []byte) 用作 io.Reader 类型

java - 从同一个类重写同一个方法两次

java - 在以下情况下是否可能发生短路评估

java - 我的埃拉托色尼筛有什么问题

java - 比较两个集合用于比较两个文本文件的添加、删除、修改

java - 并行读取文件时内存不足

java - 如何使用 java.nio.Files 创建软符号链接(symbolic link)

java - Android 套接字上的选择器行为异常