我正在迭代一个带有+ - 1500个条目的字符串列表。在每次迭代中,我再次遍历一个字符串列表,但这次有+ - 3500万个条目。申请结果非常完美。但是应用程序需要很长时间(2个多小时)来给我结果。我应该如何构建多线程以使我的应用程序更快?
结果列表的顺序并不重要。
我的其他选择是什么?
代码表示:
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秒即可获得相同的结果!没有多线程!
答案 0 :(得分:3)
您可以使用并行流:
List<String> result =
data1.parallelStream()
.filter(data2::contains)
.collect(Collectors.toList());
但是,由于您在contains()
上呼叫data2
1500次,并且由于contains()
对于列表是O(N),因此首先将其转换为HashSet可以使事情更快:{ HashSet上的{1}}是O(1)。您甚至可能不再需要多线程:
contains()
答案 1 :(得分:2)
我也同意你的想法。你现在需要做什么?
- 首先计算系统中的处理器数量。
- 根据处理器数量拆分您的记录并精确创建该线程数。 (numberofprocessor * 2 max,否则因为线程性能之间的上下文切换会降级)。
醇>
不要创建不必要的大量线程。这不会加速你的申请。根据处理器数量和系统内存大小,准确检查应创建的线程数。高效的并行处理也取决于您的机器硬件。