我正在遍历包含 +- 1500 个条目的字符串列表。在每次迭代中,我再次遍历字符串列表,但这次有 +- 3500 万个条目。应用的结果是完美的。但是应用程序需要很长时间(2 个多小时)才能给我结果。我应该如何构造多线程以使我的应用程序更快?
结果列表的顺序并不重要。
- 我是否应该将大列表(3500 万个条目)分成较小的 block 并并行迭代它们? (我怎样才能确定 block 的完美数量?)
- 我应该为小列表中的每个迭代启动一个线程吗? (这将创建 1500 个线程,我猜其中很多线程将“并行”运行)
我还有哪些其他选择?
代码表示:
List<String> result = new ArrayList<String>();
for(Iterator<String> i = data1.iterator();i.hasNext();){ //1500 entries
String val = i.next();
for(Iterator<String> j = data2.iterator();j.hasNext();){ //35 million entries
String test = j.next();
if(val.equals(test)){
result.add(val);
break;
}
}
}
for(Iterator<String> h = result.iterator();h.hasNext();){
//write to file
}
更新
在重组我的代码并实现 JB Nizet 给出的答案后,我的应用程序现在运行得更快了。现在只需 20 秒即可获得相同的结果!没有多线程!
最佳答案
您可以使用并行流:
List<String> result =
data1.parallelStream()
.filter(data2::contains)
.collect(Collectors.toList());
但是由于您在 data2
上调用了 contains()
1500 次,并且由于 contains()
对于列表来说是 O(N),首先将其转换为 HashSet 可以使事情变得更快:HashSet 上的 contains()
是 O(1)。您甚至可能不再需要多线程:
Set<String> data2Set = new HashSet<>(data2);
List<String> result =
data.stream()
.filter(data2Set::contains)
.collect(Collectors.toList());
关于java - 如何使用多线程使我的应用程序更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48967411/