高效的文本处理Java

高效的文本处理Java,java,performance,Java,Performance,我已经创建了一个应用程序来处理日志文件,但是当文件量=~20时,我遇到了一些瓶颈 这个问题来自于一个特殊的方法,它平均需要一秒钟左右的时间来大致完成,正如你可以想象的那样,当它需要完成>50次时,这是不实际的 private String getIdFromLine(String line){ String[] values = line.split("\t"); String newLine = substringBetween(values[4], "Some String

我已经创建了一个应用程序来处理日志文件,但是当文件量=~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;
  }
一行代码来自一个文件的读取,这是非常有效的,所以我不觉得有必要发布代码,除非有人要求

是否有任何方法可以改善这一点


感谢您抽出时间

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

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

我建议在操作前使用查找瓶颈。
如果您需要应用程序的性能,那么无论如何都需要分析


作为优化,我将创建一个自定义循环,以替换您的
substringBetween
方法,并消除多个
indexOf
调用

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


作为优化,我将创建一个自定义循环,以在方法之间替换您的
子字符串,并以相当快的速度摆脱多个
索引调用。

也相当快。

一些事情可能有问题:

  • 无论您是否意识到,您正在使用正则表达式。
    String.split()
    的参数被视为正则表达式。使用
    String.indexOf()
    几乎肯定是找到所需字符串特定部分的更快方法。正如赫吉格所指出的,番石榴的拆分器是一个很好的选择,因为它可以做到这一点

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

  • 我还建议使用
    String.startsWith()
    String.endsWith()
    而不是使用
    indexOf()
    执行的所有这些操作,只是为了更易于阅读


  • 有几件事可能有问题:

  • 无论您是否意识到,您正在使用正则表达式。
    String.split()
    的参数被视为正则表达式。使用
    String.indexOf()
    几乎肯定是找到所需字符串特定部分的更快方法。正如赫吉格所指出的,番石榴的拆分器是一个很好的选择,因为它可以做到这一点

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

  • 我还建议使用
    String.startsWith()
    String.endsWith()
    而不是使用
    indexOf()
    执行的所有这些操作,只是为了更易于阅读


  • 此代码中的一个主要问题是“
    拆分
    ”方法。 例如,这个:

        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());
        }
    
    私有字符串getIdFromLine3(字符串行){
    int t_指数=-1;
    对于(int i=0;i<3;i++){
    t_索引=line.indexOf(“\t”,t_索引+1);
    if(t_index=-1)返回null;
    }
    //String[]value=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)返回null;
    int p_index2=newLine.indexOf(“,p_index+1);
    if(p_index2==-1)返回null;
    字符串拆分=换行。子字符串(p_索引+1,p_索引2);
    //返回拆分[1]。子字符串(4,拆分[1]。长度();
    返回split.substring(4,split.length());
    }
    

    UPD:它的速度可能是的3倍。

    此代码中的一个主要问题是“
    拆分
    ”方法。 例如,这个:

        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());
        }
    
    私有字符串getIdFromLine3(字符串行){
    int t_指数=-1;
    对于(int i=0;i<3;i++){
    t_索引=line.indexOf(“\t”,t_索引+1);
    if(t_index=-1)返回null;
    }
    //String[]value=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)返回null;
    int p_index2=newLine.indexOf(“,p_index+1);
    if(p_index2==-1)返回null;
    字符串拆分=换行。子字符串(p_索引+1,p_索引2);
    //返回拆分[1]。子字符串(4,拆分[1]。长度();
    返回split.substring(4,split.length());
    }
    

    UPD:它可以快3倍。

    您是否可以试试正则表达式,然后发布结果,仅供比较:

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

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

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

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

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

    ,如果您还提供一个在这里解析的行的示例,这可能会很有用。。。将使代码更易于阅读。我很愿意,但它是敏感的工作数据-不确定我是否可以明智地更改它。您可以创建一个虚拟的,类似于
    xxx:aaa->bbb,ccc dd cc ee
    。我认为更有效的算法在很大程度上取决于您试图解析的数据类型。如果您还提供一个正在解析的行的示例,可能会很有用。。。会使代码更容易理解