Centos 7

时间:2016-07-27 14:57:18

标签: java io nio

我已编码使用NIO和IO读写文件。然后我在同一个磁盘环境中进行了简单的性能测试。我的测试是从一个目录中读取一个文件(~5MB)并将其写入不同的目录(同一个磁盘)。

首次测试(test.pdf):

  • NIO:Elasped time:80.457224 msec
  • IO:已用时间:4.51824毫秒

第二次测试,使用相同的文件(test.pdf):

  • NIO:Elasped time:4.732797 msec
  • IO:已用时间:4.059444毫秒

我的问题是为什么在第一次测试中,NIO花费的时间比IO长,而在第二次测试中,为什么NIO与IO几乎相同?我有点困惑。

以下是代码段(非常基本,众所周知的代码):

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();
}

1 个答案:

答案 0 :(得分:1)

第一次测试运行缓慢,因为第一次必须从磁盘存储中加载文件。

在80ms内将文件加载到7200rpm驱动器上并不一定是异常的。您的驱动器可能有大约8毫秒的搜索时间,我们不知道文件是否碎片化。

加载后,文件存储在缓冲区缓存中,后续请求(甚至是不同的进程)的加载速度要快得多。内核将文件存储在缓冲区缓存中,以加快常用文件的访问时间。

在进行基准测试时,通常最好在内存中执行测试...或预取文件内容,使其存在于缓冲区缓存中。