gpt4 book ai didi

java - ForkJoinPool 与普通递归

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:45:02 28 4
gpt4 key购买 nike

阅读关于 ForkJoinPool 后,我尝试了一个实验来测试与普通递归相比,ForkJoinPool 的实际速度有多快。

我递归地计算了一个文件夹中的文件数量,令我惊讶的是,普通递归比 ForkJoinPool

执行得更好

这是我的代码。

递归任务

class DirectoryTask extends RecursiveTask<Long> {

private Directory directory;

@Override
protected Long compute() {
List<RecursiveTask<Long>> forks = new ArrayList<>();
List<Directory> directories = directory.getDirectories();
for (Directory directory : directories) {
DirectoryTask directoryTask = new DirectoryTask(directory);
forks.add(directoryTask);
directoryTask.fork();
}
Long count = directory.getDoumentCount();
for (RecursiveTask<Long> task : forks) {
count += task.join();
}
return count;
}
}

普通递归

private static Long getFileCount(Directory directory) {
Long recursiveCount = 0L;
List<Directory> directories = directory.getDirectories();
if (null != directories) {
for (Directory d : directories) {
recursiveCount += getFileCount(d);
}
}
return recursiveCount + directory.getDoumentCount();
}

目录对象

class Directory {

private List<Directory> directories;
private Long doumentCount = 0L;

static Directory fromFolder(File file) {
List<Directory> children = new ArrayList<>();
Long documentCount = 0L;
if (!file.isDirectory()) {
throw new IllegalArgumentException("Only directories are allowed");
}
String[] files = file.list();
if (null != files) {
for (String path : files) {
File f = new File(file.getPath() + File.separator + path);
if (f.isHidden()) {
continue;
}
if (f.isDirectory()) {
children.add(Directory.fromFolder(f));
} else {
documentCount++;
}
}
}
return new Directory(children, documentCount);
}
}

结果

  • 普通递归:3 毫秒
  • ForkJoinPool:25 毫秒

哪里错了?

我只是想了解是否存在特定阈值,低于该阈值时,普通递归比 ForkJoinPool 更快。

最佳答案

生活中没有免费的东西。如果您必须将一个啤酒箱从您的汽车移动到您的公寓 - 哪个更快:手动将其运送到那里,或者先去棚屋,让手推车用它来移动那个箱子?

创建线程对象是一种“ native ”操作,它会进入底层操作系统以获取那里的资源。这可能是一个相当昂贵的操作。

意思是:仅仅在一个问题上投入“更多线程”并不会自动加快速度。与此相反的。当您的任务主要是 CPU 密集型任务时,并行执行任务可能会带来很小的 yield 。当您进行大量 IO 时,拥有多个线程可以让您总体上“减少”等待;从而提高您的吞吐量。

换句话说:Fork/Join 需要相当多的 Activity 才能完成真正的工作。将它用于只需要几毫秒的计算简直是矫枉过正。因此:您会寻找适用于更大数据集的“fork/join”操作。

要进一步阅读,您可以查看 parallel streams .那些在幕后使用 fork/join 框架;令人惊讶的是,期望任意 parallelStream 也比普通流“更快”是一种误解。

关于java - ForkJoinPool 与普通递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43433874/

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