我已经编码为使用NIO和IO读写文件。然后,我在同一磁盘环境中执行了简单的性能测试。我的测试是从目录中读取文件(〜5MB),然后将其写入其他目录(同一磁盘)中。
首次测试(test.pdf):
NIO:经过时间:80.457224毫秒
IO:经过时间:4.51824毫秒
使用相同文件(test.pdf)进行第二次测试:
NIO:经过时间:4.732797毫秒
IO:经过时间:4.059444毫秒
我的问题是,为什么在第一个测试中NIO花费的时间比IO更长,而在第二个测试中NIO花费的时间几乎与IO相同?我有点困惑。
这是代码段(非常基本,众所周知的代码):
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();
}
最佳答案
第一次测试运行缓慢,因为必须在第一次从磁盘存储中加载文件。
在80毫秒内将文件加载到7200rpm驱动器上不一定是异常的。您的驱动器的寻道时间可能约为8毫秒,我们不知道文件是否碎片化。
加载后,文件存储在缓冲区缓存中,后续请求(甚至不同的进程)的加载速度也更快。内核将文件存储在缓冲区高速缓存中,以加快对常用文件的访问时间。
进行基准测试时,通常最好在内存中完全执行测试……或预取文件内容,使其存在于缓冲区高速缓存中,这通常是个好主意。
关于java - Centos 7中的NIO和IO性能问题(第一次和第二次读写),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38616575/