1

我创建了一个应用程序来处理日志文件,但是当文件数量 = ~20 时遇到了一些瓶颈

问题来自一种特定的方法,该方法平均需要大约一秒钟才能大致完成,并且您可以想象,当它需要完成 > 50 次时,这是不切实际的

private String getIdFromLine(String line){
    String[] values = line.split("\t");
    String newLine = substringBetween(values[4], "Some String : ", "Value=");
     String[] split = newLine.split(" ");
     return split[1].substring(4, split[1].length());
}



private String substringBetween(String str, String open, String close) {
      if (str == null || open == null || close == null) {
          return null;
      }
      int start = str.indexOf(open);
      if (start != -1) {
          int end = str.indexOf(close, start + open.length());
          if (end != -1) {
              return str.substring(start + open.length(), end);
          }
      }
      return null;
  }

一行来自读取一个非常有效的文件,因此除非有人询问,否则我觉得不需要发布该代码。

无论如何,有没有改善这个的性能?

谢谢你的时间

4

6 回答 6

3

有几件事可能有问题:

  1. 无论您是否意识到,您都在使用正则表达式。to 的参数String.split()被视为正则表达式。使用String.indexOf()几乎肯定会是一种更快的方法来找到您想要的字符串的特定部分。正如 HRgiger 所指出的,Guava 的分离器是一个不错的选择,因为它就是这样做的。

  2. 你分配了一堆你不需要的东西。根据您的行有多长,您可能会创建大量不需要的额外Strings 和String[]s(以及垃圾收集它们)。避免的另一个原因String.split()

  3. 我还建议您使用 if 所做的所有这些东西,String.startsWith()只是因为它更容易阅读。String.endsWith()indexOf()

于 2012-12-14T09:35:46.243 回答
2

我会尝试使用正则表达式。

于 2012-12-14T09:12:59.027 回答
1

此代码中的主要问题之一是“ split”方法。比如这个:

    private String getIdFromLine3(String line) {
        int t_index = -1;
        for (int i = 0; i < 3; i++) {
            t_index = line.indexOf("\t", t_index+1);
            if (t_index == -1) return null;
        }
        //String[] values = line.split("\t");
        String newLine = substringBetween(line.substring(t_index + 1), "Some String : ", "Value=");
//        String[] split = newLine.split(" ");
        int p_index = newLine.indexOf(" ");
        if (p_index == -1) return null;
        int p_index2 = newLine.indexOf(" ", p_index+1);
        if (p_index2 == -1) return null;
        String split = newLine.substring(p_index+1, p_index2);

//        return split[1].substring(4, split[1].length());
        return split.substring(4, split.length());
    }

UPD:它可能快 3 倍。

于 2012-12-14T09:38:40.903 回答
0

我会建议使用VisualVM在 oprimisation 之前找到瓶颈。
如果您需要应用程序的性能,那么无论如何您都需要进行分析。

作为优化,我会制作一个自定义循环来替换你substringBetween的方法并摆脱多次indexOf调用

于 2012-12-14T09:18:04.463 回答
0

谷歌番石榴分离器也很快。

于 2012-12-14T09:23:02.887 回答
0

您是否可以尝试使用正则表达式并发布结果,仅供比较:

Pattern p = Pattern.compile("(Some String : )(.*?)(Value=)"); //remove first and last group if not needed (adjust m.group(x) to match

@Test
public void test2(){
    String str = "Long java line with Some String : and some object with Value=154345 ";
    System.out.println(substringBetween(str));      
}

private String substringBetween(String str) {       
    Matcher m = p.matcher(str);
    if(m.find(2)){
        return m.group(2);          
    }else{
        return null;
    }
}

如果这更快找到一个结合了这两个函数的正则表达式

于 2012-12-14T09:49:59.827 回答