gpt4 book ai didi

java - Fork 和 Join 与单线程程序的比较

转载 作者:行者123 更新时间:2023-12-02 04:53:33 26 4
gpt4 key购买 nike

我正在尝试开始使用 Fork-Join 框架来完成较小的任务。当我启动示例时,我尝试复制 mp3 文件

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class DeepFileCopier extends RecursiveTask<String>{

/**
*
*/
private static final long serialVersionUID = 1L;

private static Path startingDir = Paths.get("D:\\larsen\\Music\\");
private static List<Path> listOfPaths = new ArrayList<>();
private int start, end;

public static void main(String[] args) throws IOException
{
long startMillis = System.currentTimeMillis();
Files.walkFileTree(startingDir, new CustomFileVisitor());
final DeepFileCopier deepFileCopier = new DeepFileCopier(0,listOfPaths.size());
final ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
pool.invoke(deepFileCopier);
System.out.println("With Fork-Join " + (System.currentTimeMillis() - startMillis));
long secondStartMillis = System.currentTimeMillis();
deepFileCopier.start = 0;
deepFileCopier.end = listOfPaths.size();
deepFileCopier.computeDirectly();
System.out.println("Without Fork-Join " + (System.currentTimeMillis() - secondStartMillis));

}

private static class CustomFileVisitor extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
{
if (file.toString().endsWith(".mp3")) {
listOfPaths.add(file);
}
return FileVisitResult.CONTINUE;
}
}

@Override
protected String compute() {
int length = end-start;
if(length < 4) {
return computeDirectly();
}
int split = length / 2;
final DeepFileCopier firstHalfCopier = new DeepFileCopier(start, start + split);
firstHalfCopier.fork();
final DeepFileCopier secondHalfCopier = new DeepFileCopier(start + split, end);
secondHalfCopier.compute();
firstHalfCopier.join();
return null;
}

private String computeDirectly() {
for(int index = start; index< end; index++) {
Path currentFile = listOfPaths.get(index);
System.out.println("Copying :: " + currentFile.getFileName());
Path targetDir = Paths.get("D:\\Fork-Join Test\\" + currentFile.getFileName());
try {
Files.copy(currentFile, targetDir, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

private DeepFileCopier(int start, int end ) {
this.start = start;
this.end = end;
}

}

比较我注意到的性能 -

使用 fork 连接 149714没有 Fork-Join 146590

我正在使用双核机器。我预计工作时间会减少 50%,但使用 Fork-Join 的部分比单线程方法多花了 3 秒。如果有什么不正确的地方,请告诉我。

最佳答案

您的问题不太适合从普通系统上的多线程中受益。执行时间用于复制所有文件。但这受到按顺序处理文件的硬盘的限制。

如果您运行 CPU 密集度更高的任务,您应该注意到差异。出于测试目的,您可以尝试以下操作:

private String computeDirectly() {
Integer nonsense;
for(int index = start; index< end; index++) {
for( int j = 0; j < 1000000; j++ )
nonsense += index*j;
}
return nonsense.toString();
}

在我的系统(i5-2410M)上将打印:

With Fork-Join 2628
Without Fork-Join 6421

关于java - Fork 和 Join 与单线程程序的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29002875/

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