Java性能优化重复地用一个字符串替换另一个字符串
我正在开发CMS的HttpServlet扩展(插件),它的任务是过滤HTML响应 在我的Java性能优化重复地用一个字符串替换另一个字符串,java,html,string,performance,optimization,Java,Html,String,Performance,Optimization,我正在开发CMS的HttpServlet扩展(插件),它的任务是过滤HTML响应 在我的filterResponse方法中,我以字符串形式获取请求的text/html,这是其中的三个参数之一 具体来说,我需要做的是在html字符串中搜索特定的URL模式,并稍微修改它。现在,当一个大文档中有很多链接时,这可能是一个繁重的操作,我希望尽可能优化这个过程 我的第一个版本只是在字符串上使用了replace(“://www.”,“://www-x1.”)方法 然后,在当前版本中,我使用匹配器和模式类。 示
filterResponse
方法中,我以字符串形式获取请求的text/html
,这是其中的三个参数之一
具体来说,我需要做的是在html字符串中搜索特定的URL模式,并稍微修改它。现在,当一个大文档中有很多链接时,这可能是一个繁重的操作,我希望尽可能优化这个过程
我的第一个版本只是在字符串上使用了replace(“://www.”,“://www-x1.”)
方法
然后,在当前版本中,我使用匹配器
和模式
类。
示例代码:
@Override
public String filterResponse(HttpServletRequest request, String textHtml, String contentType) throws Exception {
Pattern pattern = Pattern.compile("://www.");
Matcher m = pattern.matcher(textHtml);
String response = m.replaceAll("://www-x1.");
.....
.....
return response;
}
在实际代码中,我在静态字段中预编译模式(Pattern),并对匹配的字符串执行相同的操作
有什么办法可以加快速度吗?
可能转换为DOM对象或其他XML对象以获得更快的查询方法?等等。首先,在没有模式的情况下使用模式匹配。这不仅浪费性能,而且是一个错误。对于用作图案的
://www.“
,最后一个点与任何字符匹配
如果要替换简单的字符串
而不是模式,可以使用而不是String.replaceAll
。这修复了错误并节省了在内部创建模式
和匹配器
的全部开销
如果要使用正则表达式匹配器,最简单的修复方法是使用Pattern.compile(“://www.”,Pattern.LITERAL)
停止解释特殊字符,并允许对整个序列使用Boyer–Moore算法。然而,只有当您能够存储并重用准备好的模式时,这才会有回报
此外,replaceAll
方法还提供了一种功能,可以将对替换字符串中匹配组的反向引用进行解释。由于您没有使用此功能,您可以通过自己实现替换循环来节省与该功能相关的开销。作为奖励,您可以使用StringBuilder
,其中Matcher
使用StringBuffer
,但这只是一个小小的改进
static String replace(String source)
{// the pattern would be better off being re-usable stored in a static field
final Pattern pattern = Pattern.compile("://www.", Pattern.LITERAL);
final Matcher m = pattern.matcher(source);
boolean result = m.find();
if (result) {
StringBuilder sb = new StringBuilder(source.length()+16);
int p=0;
do {
sb.append(source, p, m.start()).append("://www-x1.");
p=m.end();
} while (m.find());
sb.append(source, p, source.length());
return sb.toString();
}
return source;
}
但正如前面所说,对于这个简单的例子,完全不使用regex可能是更好的选择。我认为对于单个替换(即一个搜索字符串,一个替换),这接近最优。如果您使用不同的字符串重复执行此操作,那么肯定有办法对其进行优化。转换到DOM(或转换回DOM)不太可能更快。您如何比较解决方案的性能?与第二种方法相比,第一种方法的速度有多快?我猜第一种简单的方法是最快的方法。不要每次输入这个func时都编译模式。在外面做一次。@Artur我做了。更改了我在底部的措辞,使之clearer@ThomasUhrig我在那里还没做多少工作。我想听听有更多专业知识的人的意见,看看我是否绝对应该用另一种方式来做,或者避免使用当前的解决方案。我后来看到,您在问题中提到的是replace
,而不是replaceAll
。但是你知道其中的区别吗?从replace
迁移到regex并不是一个自然的选择……我必须承认,我不知道开销的差异。因此,您建议使用最简单的解决方案,即Stringreplace
方法?或者差异是边际的?我将模式对象声明为静态最终字段。我将使用最简单的解决方案,String.replace
。我的答案的模式示例仅适用于较大的搜索字符串,但“://www.“
相当简短。如果有疑问,请对这两种变体进行基准测试。回答很好,谢谢!:)我将把这个问题留一段时间,看看是否有更多好的建议。在这篇文章中,Stringreplace()
也是用regex实现的。Apache StringUtilsreplace()
是用indexOf
和StringBuffer实现的,因此应该更快。你怎么认为?