【发布时间】: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,我刚刚进行了两次测试。