我有一个用Java编写的程序,它读入的文件只是一个字符串列表到LinkedHashMap中。然后它需要一个由两列组成的第二个文件,并且对于每一行,查看右手术语是否与HashMap中的一个术语匹配。问题是它运行得很慢。
这是一个代码片段,它将第二个文件与HashMap术语进行比较:
String output = "";
infile = new File("2columns.txt");
try {
in = new BufferedReader(new FileReader(infile));
} catch (FileNotFoundException e2) {
System.out.println("2columns.txt" + " not found");
}
try {
fw = new FileWriter("newfile.txt");
out = new PrintWriter(fw);
try {
String str = in.readLine();
while (str != null) {
StringTokenizer strtok = new StringTokenizer(str);
strtok.nextToken();
String strDest = strtok.nextToken();
System.out.println("Term = " + strDest);
//if (uniqList.contains(strDest)) {
if (uniqMap.get(strDest) != null) {
output += str + "\r\n";
System.out.println("Matched! Added: " + str);
}
str = in.readLine();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.print(output);
从最初的ArrayList切换到LinkedHashMap,我获得了性能提升,但它仍然需要很长时间。我该怎么做才能加快速度呢?
答案 0 :(得分:4)
您的主要瓶颈可能是您正在为while循环的每次迭代重新创建StringTokenizer。将其移出循环可能会有很大帮助。通过在while循环外移动String定义可以获得较小的加速。
最大的加速可能来自使用StreamTokenizer。请参阅下面的示例。
哦,使用HashMap而不是LinkedHashMap,因为@Doug Ayers在上面的评论中说:)
并且@MДΓΓБДLL建议对代码进行分析。结帐Eclipse Profiling Example
Reader r = new BufferedReader(new FileReader(infile));
StreamTokenizer strtok = new StreamTokenizer(r);
String strDest ="";
while (strtok.nextToken() != StreamTokenizer.TT_EOF) {
strDest=strtok.sval; //strtok.toString() might be safer, but slower
strtok.nextToken();
System.out.println("Term = " + strtok.sval);
//if (uniqList.contains(strDest)) {
if (uniqMap.get(strtok.sval) != null) {
output += str + "\r\n";
System.out.println("Matched! Added: " + strDest +" "+ strtok.sval);
}
str = in.readLine();
}
最后一个想法是(并且我对这个问题没有信心)如果你最后一次完成,写入文件也可能会更快。即将所有比赛存储在某种缓冲区中,并在一次点击中进行写作。
答案 1 :(得分:2)
StringTokenizer是一个遗留类。建议的替换是字符串“split”方法。
有些部分可能会合并。一次尝试就可以有多次捕获。
使用HashMap而不是LinkedHashMap的建议是一个很好的建议。由于不需要维护列表结构,因此获取和放入smidgeon的性能更快。
“output”字符串应该是StringBuilder而不是String。这可能会有很大帮助。