2

我有一个用 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 获得了性能提升,但仍然需要很长时间。我能做些什么来加快速度?

4

2 回答 2

4

您的主要瓶颈可能是您正在为 while 循环的每次迭代重新创建一个 StringTokenizer。将其移出循环可能会有很大帮助。通过将 String 定义移到 while 循环之外可以获得较小的加速。

最大的加速可能来自使用StreamTokenizer。请参阅下面的示例。

哦,就像@Doug Ayers 在上面的评论中所说的那样,使用 HashMap 而不是 LinkedHashMap :)

@MДΓΓ БДLL 对分析您的代码的建议很受欢迎。签出这个Eclipse 分析示例

    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();
}

最后一个想法是(我对此没有信心)如果你在最后一次完成写入文件也可能会更快。即,将所有匹配项存储在某种缓冲区中,然后一次完成写入。

于 2012-04-19T04:41:23.337 回答
2

StringTokenizer 是一个遗留类。推荐的替换是字符串“split”方法。

一些尝试可能会合并。一次尝试可以有多个捕获。

使用 HashMap 而不是 LinkedHashMap 的建议是一个很好的建议。由于不需要维护列表结构,因此获取和放入的性能更快。

“输出”字符串应该是 StringBuilder 而不是 String。这会很有帮助。

于 2012-04-19T04:53:23.910 回答