我已编码使用NIO和IO读写文件。然后我在同一个磁盘环境中进行了简单的性能测试。我的测试是从一个目录中读取一个文件(~5MB)并将其写入不同的目录(同一个磁盘)。
首次测试(test.pdf):
第二次测试,使用相同的文件(test.pdf):
我的问题是为什么在第一次测试中,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();
}
答案 0 :(得分:1)
第一次测试运行缓慢,因为第一次必须从磁盘存储中加载文件。
在80ms内将文件加载到7200rpm驱动器上并不一定是异常的。您的驱动器可能有大约8毫秒的搜索时间,我们不知道文件是否碎片化。
加载后,文件存储在缓冲区缓存中,后续请求(甚至是不同的进程)的加载速度要快得多。内核将文件存储在缓冲区缓存中,以加快常用文件的访问时间。
在进行基准测试时,通常最好在内存中执行测试...或预取文件内容,使其存在于缓冲区缓存中。