高效的文本处理Java
我已经创建了一个应用程序来处理日志文件,但是当文件量=~20时,我遇到了一些瓶颈 这个问题来自于一个特殊的方法,它平均需要一秒钟左右的时间来大致完成,正如你可以想象的那样,当它需要完成>50次时,这是不实际的高效的文本处理Java,java,performance,Java,Performance,我已经创建了一个应用程序来处理日志文件,但是当文件量=~20时,我遇到了一些瓶颈 这个问题来自于一个特殊的方法,它平均需要一秒钟左右的时间来大致完成,正如你可以想象的那样,当它需要完成>50次时,这是不实际的 private String getIdFromLine(String line){ String[] values = line.split("\t"); String newLine = substringBetween(values[4], "Some String
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
。我认为更有效的算法在很大程度上取决于您试图解析的数据类型。如果您还提供一个正在解析的行的示例,可能会很有用。。。会使代码更容易理解