我有一个Java程序,它基本上逐行从文件读取并将行存储到一个集合中。该文件包含超过30000000行。我的程序在开始时运行速度很快,但在处理20000000行后速度变慢,甚至太慢等待。有人可以解释为什么会发生这种情况,我怎样才能再次加速程序?
感谢。
public void returnTop100Phases() {
Set<Phase> phaseTreeSet = new TreeSet<>(new Comparator<Phase>() {
@Override
public int compare(Phase o1, Phase o2) {
int diff = o2.count - o1.count;
if (diff == 0) {
return o1.phase.compareTo(o2.phase);
} else {
return diff > 0 ? 1 : -1;
}
}
});
try {
int lineCount = 0;
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(new File("output")), StandardCharsets.UTF_8));
String line = null;
while ((line = br.readLine()) != null) {
lineCount++;
if (lineCount % 10000 == 0) {
System.out.println(lineCount);
}
String[] tokens = line.split("\\t");
phaseTreeSet.add(new Phase(tokens[0], Integer.parseInt(tokens[1])));
}
br.close();
PrintStream out = new PrintStream(System.out, true, "UTF-8");
Iterator<Phase> iterator = phaseTreeSet.iterator();
int n = 100;
while (n > 0 && iterator.hasNext()) {
Phase phase = iterator.next();
out.print(phase.phase + "\t" + phase.count + "\n");
n--;
}
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
答案 0 :(得分:0)
查看运行时行为,这显然是一个内存问题。事实上,我的测试甚至在大约500万之后就已经破了,因为GC已经超出了限制范围而且#39;在Java8上。如果我通过添加
来限制phaseTreeSet的大小if (phaseTreeSet.size() > 100) { phaseTreeSet.pollLast(); }
它快速通过。它变慢的原因是,它使用更多的内存,因此垃圾收集需要更长的时间。但每次需要更多内存之前,它必须再次进行大量垃圾回收。显然有很多记忆要做,而且每次都慢一点......
为了加快速度,你需要让内存不足。也许只保留像我一样的顶级阶段,或使用某种数据库。