Java转义HTML – 字符串替换慢吗?

我有一个Java应用程序,它大量使用大文件,读取,处理并通过SolrEmbeddedServer( http://lucene.apache.org/solr/ )。

其中一个函数执行基本的HTML转义:

private String htmlEscape(String input) { return input.replace("&", "&").replace(">", ">").replace("<", "<") .replace("'", "&apos;").replaceAll("\"", """); } 

在分析应用程序时,该程序在此function中花费大约58%的时间,替换中总共占47%,在replaceAll中占11%。

现在,Java取代速度是否缓慢,或者我是否在正确的道路上,我是否应该认为该程序的效率足以在Java中出现瓶颈,而不是在我的代码中? (或者我替换错了?)

提前致谢!

对于html转义,您可以使用commons-lang中的 StringEscapeUtils.escapeHtml(input) 。 据推测,它在那里以更有效的方式实施。

这当然不是进行大量替换的最有效方法。 由于字符串是不可变的,因此每个.replace()都会导致构造一个新的String对象。 对于您给出的示例,每次调用此函数都会导致临时创建6个String对象。

考虑到您提供的示例,最简单的解决方案是使用现有的库函数进行HTML实体编码。 Apache commons StringEscapeUtils是一个选项。 另一个是HTMLEntities

Apache Commons Lang在其StringEscapeUtils类中有一个非常有效的escapeHtml方法。

它相当聪明,并且不会以您描述的方式使用字符串替换,而是遍历字符,在找到它们时用适当的实体替换字符。

我没有任何基准,但如果这些东西是你的代码的关键路径,那么你就可以使用这个现成的,更快的解决方案。

每次调用replace都会返回一个新的String。 每次调用此函数时,您基本上都会创建四个字符串副本,这些字符串将立即被丢弃。 如果输入足够大,这可能是浪费。

我建议修改你的算法,这样你就不需要执行N次replace操作(每次需要扫描字符串),而只扫描列表一次:

 //psuedocode Map replacements = new HashMap(); replacements.put("&", "&"); replacements.put(">", ">"); ... private String htmlEscape(String input) { StringBuilder sb = new StringBuilder(input.length()); for (char c: sb.toCharArray()) { if (replacements.containsKey(c)) { sb.append(replacements.get(c)); else { sb.append(c); } return sb.toString(); } 

使用http://commons.apache.org/lang/更容易,也更标准。 这非常简单。

使用多种替换方法的方法可能会很慢。

查看Apache Commons Lang的StringEscapeUtils,以便快速实现转义HTML实体。

String.replace的一般算法有点复杂,但它不应该那么糟糕。 看看代码,它实际上是使用正则表达式实现的,所以不会快 – ick。

显然,您可以通过逐个字符迭代来编写更快的代码。 可能首先确定准确的长度。

您可能想要考虑如何处理[ -~]之外的字符。 您可能还想使用已实现该function的库。

对于休闲读者来说,Html转义字段中有一个新玩家: unbescape 。

可以像这样对HTML代码执行unescape操作:

 final String unescapedText = HtmlEscape.unescapeHtml(escapedText);