我正在进行xml解析并执行一些使用大量内存空间的字符串replaceAll
,如下图所示。
代码如下:
private final String getText() {
// special handling for apostrophe encoding
// site will expect both ' , ' and %27.
// change %27 or 'or ' to '
return _text.toString().trim().replaceAll("'", "'")
.replaceAll("'", "'").replaceAll("%27", "'");
}
getText()
方法经常从SAXParser的endElement()
方法调用。
任何人都可以建议如何更改使用较小堆空间的此功能
![跟踪] [1]
答案 0 :(得分:6)
使用replace()
代替replaceAll()
。 replaceAll()
使用regular expression,您不需要它们,而且它们也是开销。
答案 1 :(得分:3)
使用正则表达式进行简单的字符串替换是非常昂贵的。 我只想构建一个这样的StringBuilder实例:
StringBuilder sb = new StringBuilder();
while (not end of _text) {
find next '&'
if the next substring is in (' ') etc.
append the prev portion of _text to sb
append replacement char
set the beginning of the chunk to the next char
}
return sb.toString();
答案 2 :(得分:3)
由于_text
已经是StringBuffer
,您可以使用indexOf(String str)
和replace(int start, int end, String str)
。这样,您根本不会创建临时String
个对象。
使用类似的功能:
private void replace(StringBuffer buff,String toReplace,String replaceTo){
int start;
while ((start=buff.indexOf(toReplace))>=0)
buff.replace(start,start+toReplace.length(),replaceTo);
}
并为您调用getText()
中的函数,对于每个组合,例如:
String replaceTo=",";
replace(_text,"'",replaceTo);
replace(_text,"'",replaceTo);
replace(_text,"%27",replaceTo);
return _text.toString();
答案 3 :(得分:1)
您的replaceAll方法在String
上调用,这是不可变的。因此,每次修改时都必须创建一个全新的字符串(在这种情况下为3次)。如果您使用StringBuilder
代替,您的字符串将是可变的,并且每次更换内容时都不需要再次分配。
顺便说一句,在StringBuilders中没有像你需要的那样“替换”,所以你必须反复使用indexOf
找到你的违规字符串,并在结果上replace
。 trim()就在那里。
答案 4 :(得分:1)
您可以一次性完成所有3次替换
text.replaceAll("('|&39;|%27)", "'");
它比3次连续替换效率高3倍,因为每次替换都可能创建一个新的String
答案 5 :(得分:1)
由于您在SAX中获取文本,因此必须来自此处
characters(char[] ch, int start, int length)
你必须在字段中保存这些args,在endElement()上你可以替换为
StringBuilder sb = new StringBuilder();
for (int i = start; i < length; i++) {
// %27
if (ch[i] == '%' && length - i > 2 && ch[i + 1] == '2' && ch[i + 2] == '7') {
sb.append('\'');
i += 2;
// '
} else if (
...
// '
} else if (
...
} else {
sb.append(ch[i]);
}
}
String res = sb.toString();
代码很长但效率很高,你也可以添加修剪