Java Performance优化重复将一个String替换为另一个String

时间:2013-11-28 10:30:05

标签: java html string performance optimization

我正在处理CMS的HttpServlet扩展(插件),其任务是过滤HTML响应。

在我的filterResponse方法中,我在字符串中获取请求的text/html,这是其中的三个参数之一。

具体来说,我需要做的是在html字符串中搜索特定的URL模式并稍微修改它。现在,当大型文档中有许多链接时,这可能是一个繁重的操作,我想尽可能地优化这个过程。

我的第一个版本只是在String上使用了replace("://www.", "://www-x1.")方法。

然后,在当前版本中,我使用MatcherPattern类。 示例代码:

@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对象以获得更快的查询方法?等

1 个答案:

答案 0 :(得分:0)

首先,您在没有模式的情况下使用模式匹配。这不仅浪费性能,而且是一个错误。对于用作模式的"://www.",最后一个点匹配任何字符

如果您想要替换简单的String而不是模式,则可以使用String.replace代替String.replaceAll。这样可以解决错误并节省内部创建PatternMatcher的全部费用。

如果要使用正则表达式匹配器,最简单的解决方法是使用Pattern.compile("://www.", Pattern.LITERAL)来停止解释特殊字符,并允许对整个序列使用Boyer-Moore算法。但是,如果您可以存储和重复使用准备好的模式,这只会得到回报。

此外,replaceAll方法提供了在替换String中解释对匹配组的反向引用的功能。由于您没有使用此功能,因此您可以通过自己实施替换循环来节省与该功能相关的开销。作为奖励,您可以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;
}

但正如已经说过的那样,完全没有使用正则表达式可能是这个简单案例的更好选择。