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

Ale*_*ien 5 java io nio

我在嵌入式Linux设备上使用Java 1.5,并希望读取具有2MB int值的二进制文件.(现在4字节Big Endian,但我可以决定,格式)

使用DataInputStream通过BufferedInputStream 使用dis.readInt()),这500万个电话需要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();
Run Code Online (Sandbox Code Playgroud)

更新:评估答案:

在PC上,使用IntBuffer方法的Memory Map是我设置中最快的.
在嵌入式设备上,没有jit,java.io DataiInputStream.readInt()有点快(17s,与使用IntBuffer的MemMap相比,20s)

最后的结论:通过算法更改可以更轻松地实现显着的加速.(初始化文件较小)

Mic*_*sel 4

我不知道这是否会比 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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 在 PC 上它是最快的解决方案,但在没有 JIT 的嵌入式上它需要 20 秒,所以 java io 仍然是最快的。有趣的... (2认同)