【问题标题】:NIO and IO performance issue (first and second read and write) in Centos 7Centos 7 中的 NIO 和 IO 性能问题(第一次和第二次读写)
【发布时间】:2016-07-27 14:57:18
【问题描述】:

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

第一次测试(test.pdf):

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

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

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

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

这里是sn-p的代码(非常基础,众所周知的代码):

int BUFFER_SIZE = 64 * 1024;

蔚来:

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

【问题讨论】:

  • 您在使用 SAN/慢速磁盘吗?一种可能性是,您的第一个测试将文件从 san 加载到缓冲区中,并且所有连续的测试都从内存中运行。至少因为 java7 io 在底层使用了 nio,只要它提供了性能提升,所以 4.7 到 4.1 将在我的预期之内。
  • 感谢您的回复。不,我没有使用 SAN/慢速磁盘。我正在我的工作站上进行测试。它是 Pentium 5,HDD 7200 rpm。
  • 你运行了多少次测试?
  • 在测试之前是否已经加载了使用的 nio 类(Java 按需加载它们)?将几十个类文件加载到 JVM 中可能会对读取时间产生重大影响。
  • @chrylis,我刚刚进行了两次测试。

标签: java io nio


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多