MFH
MFH

Reputation: 367

NIO and IO performance issue (first and second read and write) in Centos 7

I have coded to read and write file using NIO and IO. Then I have performed simple performance test in the same disk environment. My test was to read a file (~5MB) from a directory and write it in the different directory (same disk).

First test (test.pdf):

Second test, using same file (test.pdf):

My question is why in the first test, NIO took longer time than IO and in the second test why NIO took almost same time as IO? I am little bit confused.

Here is the code snippet (very basic, well known code):

int BUFFER_SIZE = 64 * 1024;

NIO:

ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
try (SeekableByteChannel seekableChannelToRead =  Files.newByteChannel(readFilePath,EnumSet.of(StandardOpenOption.READ));
     SeekableByteChannel seekableChannelToWrite  = Files.newByteChannel(writeFilePath, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE))) {

  Long startTime = System.nanoTime();
  int byteCount = 0;

  while ((byteCount = seekableChannelToRead.read(buffer)) > 0) {
        buffer.flip();
        seekableChannelToWrite.write(buffer);
        buffer.clear();
  }

  Long elapsedTime = System.nanoTime() - startTime;
  System.out.println("FileName: " + path.getFileName() + "; Elapsed Time is " + (elapsedTime / 1000000.0) + " msec");

} catch (Exception e) {
    e.printStackTrace();
}

IO:

try (FileInputStream in = new FileInputStream(path.toFile());
   FileOutputStream out = new FileOutputStream(writeFilePath.toFile())) {
   Long startTime = System.nanoTime();
   byte[] byteArray = new byte[BUFFER_SIZE]; // byte-array
   int bytesCount;
   while ((bytesCount = in.read(byteArray)) != -1) {
        out.write(byteArray, 0, bytesCount);
   }
   Long elapsedTime = System.nanoTime() - startTime;
   System.out.println("Elapsed Time is " + (elapsedTime / 1000000.0) + " msec");
} catch (IOException ex) {
    ex.printStackTrace();
}

Upvotes: 0

Views: 293

Answers (1)

misterbiscuit
misterbiscuit

Reputation: 1787

The first test ran slow because the file had to be loaded from your disk storage the first time.

Loading the file on a 7200rpm drive in 80ms is not necessarily abnormal. Your drive probably has a seek time of about 8ms and we don't know if the file is fragmented or not.

After loading the file is stored in buffer cache and subsequent requests (even different processes) are loaded much faster. The kernel stores files in the buffer cache to speedup access time for commonly used files.

When doing benchmarks, its usually a good idea to perform the tests entirely in memory... or prefetch the file contents so it exists in the buffer cache.

Upvotes: 1

Related Questions