Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java性能优化重复地用一个字符串替换另一个字符串_Java_Html_String_Performance_Optimization - Fatal编程技术网

Java性能优化重复地用一个字符串替换另一个字符串

Java性能优化重复地用一个字符串替换另一个字符串,java,html,string,performance,optimization,Java,Html,String,Performance,Optimization,我正在开发CMS的HttpServlet扩展(插件),它的任务是过滤HTML响应 在我的filterResponse方法中,我以字符串形式获取请求的text/html,这是其中的三个参数之一 具体来说,我需要做的是在html字符串中搜索特定的URL模式,并稍微修改它。现在,当一个大文档中有很多链接时,这可能是一个繁重的操作,我希望尽可能优化这个过程 我的第一个版本只是在字符串上使用了replace(“://www.”,“://www-x1.”)方法 然后,在当前版本中,我使用匹配器和模式类。 示

我正在开发CMS的HttpServlet扩展(插件),它的任务是过滤HTML响应

在我的
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并不是一个自然的选择……我必须承认,我不知道开销的差异。因此,您建议使用最简单的解决方案,即String
replace
方法?或者差异是边际的?我将模式对象声明为静态最终字段。我将使用最简单的解决方案,
String.replace
。我的答案的模式示例仅适用于较大的搜索字符串,但
“://www.“
相当简短。如果有疑问,请对这两种变体进行基准测试。回答很好,谢谢!:)我将把这个问题留一段时间,看看是否有更多好的建议。在这篇文章中,String
replace()
也是用regex实现的。Apache StringUtils
replace()
是用
indexOf
和StringBuffer实现的,因此应该更快。你怎么认为?