gpt4 book ai didi

java - 为什么 nio.files.copy 比 nio.fileChannel 复制慢很多?

转载 作者:搜寻专家 更新时间:2023-11-01 01:16:04 31 4
gpt4 key购买 nike

我是初级 Java 程序员。
今天,我练习了如何在 java 中复制文件并尝试按照本教程进行操作 http://www.journaldev.com/861/4-ways-to-copy-file-in-java
完成本教程后,我运行了 JMH Benchmark 来检查性能,并使用了一个 57MB 的 txt 文件。
而且 nioFiles 和 NIOChannel 之间存在性能差距,比我预期的要大。

Benchmark                                   Mode  Cnt   Score   Error  Units
CompressTest.fileCopyUsingNIOChannelClass thrpt 10 22.465 ± 2.996 ops/s
CompressTest.fileCopyWithNIOFiles thrpt 10 0.843 ± 0.488 ops/s

这是我使用的代码

    @Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
@State(Scope.Benchmark)
public class CompressTest
{
final static Path source = Paths.get("c:/temp/system.out.lambda.txt");
final static Path target = Paths.get("c:/temp/copied.lambda.txt");

public static void main(String[] args) throws RunnerException, IOException {
Main.main(args);
}

@Benchmark
public static void fileCopyWithNIOFiles() throws IOException{
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
@Benchmark
public static void fileCopyUsingNIOChannelClass() throws IOException
{
File fileToCopy = new File("c:/temp/system.out.lambda.txt");
FileInputStream inputStream = new FileInputStream(fileToCopy);
FileChannel inChannel = inputStream.getChannel();

File newFile = new File("c:/temp/testcopied.txt");
FileOutputStream outputStream = new FileOutputStream(newFile);
FileChannel outChannel = outputStream.getChannel();

inChannel.transferTo(0, fileToCopy.length(), outChannel);
inputStream.close();
outputStream.close();
}
}

所以我想问一下,我是不是做错了什么?或者你能解释为什么会这样吗?


有人问,所以我尝试了另一个文件。 348MB avi 文件,结果如下。

Benchmark                                   Mode  Cnt  Score   Error  Units
CompressTest.fileCopyUsingNIOChannelClass thrpt 10 3.142 ± 0.738 ops/s
CompressTest.fileCopyWithNIOFiles thrpt 10 1.991 ± 0.350 ops/s

使用 nioFile 进行静态文件复制比使用 NIOChannel 慢。


我刷新了所有内容并再次测试,这就是结果。使用 57MB 的 txt 文件并将预热迭代设置为 10。

Benchmark                                   Mode  Cnt   Score   Error  Units
CompressTest.fileCopyUsingNIOChannelClass thrpt 10 23.442 ± 3.224 ops/s
CompressTest.fileCopyWithNIOFiles thrpt 10 12.328 ± 2.128 ops/s

这个结果比第一个更容易接受,但是nioFile复制的速度仍然是NIOChannel的将近一半。

附言: 如果有更好的复制文件的方法,请告诉我。我真的很想了解更多关于 java 的知识,谢谢。

最佳答案

TL;DR - This is the caching issue

在运行基准测试时,在任务管理器中打开性能选项卡,您将看到差异的来源。

Files.copy 测试期间,您可能会看到磁盘写入速度很高。但是当 transferTo 测试运行时,磁盘将几乎空闲!这意味着实际上没有数据写入设备 - 复制是在内存中执行的。这显然要快得多。

Java Files.copy 方法是使用 CopyFileEx 实现的WinAPI 函数。没有明确说明 CopyFileEx 在内部是如何工作的,但观察到它会执行一些实际的磁盘 I/O。

依次 transferTo 执行一系列 ReadFile/WriteFile 调用。 WriteFile函数不保证数据立即写入磁盘。它可能会将数据放入 OS 磁盘缓存中,稍后在后台执行实际设备 I/O。

关于java - 为什么 nio.files.copy 比 nio.fileChannel 复制慢很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34769548/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com