我有包含源目标节点和阈值的大文本文件。我将所有不同的节点存储在HashSet中,然后根据用户阈值过滤边缘并将过滤后的节点存储在分离的哈希集中。所以我想找到一个尽可能快地进行处理的方法。
public class Simulator {
static HashSet<Integer> Alledgecount = new HashSet<>();
static HashSet<Integer> FilteredEdges = new HashSet<>();
static void process(BufferedReader reader,double userThres) throws IOException {
String line = null;
int l = 0;
BufferedWriter writer = new BufferedWriter( new FileWriter("C:/users/mario/desktop/edgeList.txt"));
while ((line = reader.readLine()) != null & l < 50_000_000) {
String[] intArr = line.split("\\s+");
checkDuplicate(Integer.parseInt(intArr[1]), Integer.parseInt(intArr[2]), Alledgecount);
double threshold = Double.parseDouble(intArr[3]);
if(threshold > userThres) {
writeToFile(intArr[1],intArr[2],writer);
checkDuplicate(Integer.parseInt(intArr[1]), Integer.parseInt(intArr[2]), FilteredEdges);
}
l++;
}
writer.close();
}
static void writeToFile(String param1,String param2,Writer writer) throws IOException {
writer.write(param1+","+param2);
writer.write("\r\n");
}
图表类执行BFS并将节点写入单独的文件中。我已完成处理,不包括某些功能,时间如下。
在过程中读取了5000万行的计时()
without calling BFS(),checkDuplicates,writeAllEdgesToFile() -> 54s
without calling BFS(),writeAllEdgesToFile() -> 50s
without calling writeAllEdgesToFile() -> 1min
在过程中读取了3亿行的计时()
without calling writeAllEdges() 5 min
答案 0 :(得分:3)
读取文件不仅取决于CPU核心
对文件的IO操作将受到经典磁盘的物理限制的限制,这与CPU核心无法并行操作。
你可以做的是为IO操作提供一个线程以及其他用于数据处理的线程,但只有在数据处理足够长以使Thread
为此任务创建Thread
时才有意义{{{ 1}}在CPU调度方面有成本。
答案 1 :(得分:2)
使多线程Java程序正常运行可能非常棘手。它需要对同步问题等方面有一些深刻的理解。如果没有必要的知识/经验,您将很难搜索有时发生但不可靠再现的错误。
因此,在尝试多线程之前,请先找出是否有更简单的方法来实现可接受的性能:
找到花费时间的程序部分!
第一个问题:它是I / O还是CPU?看看任务管理器。您的单线程程序是否占用一个核心(例如,4核计算机上的CPU接近25%)?如果它远远低于那个,那么I / O必须是限制因素,改变你的程序可能不会有太多帮助 - 购买更快的HD。 (在某些情况下,执行I / O的软件风格可能会影响硬件性能,但这种情况很少见。)
如果是CPU,使用分析器,例如JDK中包含的JVisualVM,用于查找占用大部分运行时并考虑备选方案的方法。一个候选人可能是line.split("\\s+")
,使用正则表达式。它们很慢,特别是如果表达式没有事先编译成模式 - 但这只不过是一个猜测,而探查器很可能会告诉你一些非常不同的地方。