[英]Java escape HTML - string replace slow?
我有一个Java应用程序,它大量使用大文件,读取,处理并通过SolrEmbeddedServer( http://lucene.apache.org/solr/ )。
其中一个函数执行基本的HTML转义:
private String htmlEscape(String input)
{
return input.replace("&", "&").replace(">", ">").replace("<", "<")
.replace("'", "'").replaceAll("\"", """);
}
在分析应用程序时,该程序在此功能中花费大约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<Char, String> replacements = new HashMap<String, String>();
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/更容易,更标准。 这非常简单。
对于休闲读者来说,Html逃生领域有一个新玩家: unbescape 。
对HTML代码的unescape操作可以这样完成:
final String unescapedText = HtmlEscape.unescapeHtml(escapedText);
使用多种替换方法的方法可能很慢。
查看Apache Commons Lang的StringEscapeUtils,以便快速实现转义HTML实体。
String.replace
的一般算法有点复杂,但它不应该那么糟糕。 看看代码,它实际上是使用正则表达式实现的,所以不会快 - ick。
显然,您可以通过逐个字符迭代来编写更快的代码。 可能首先确定准确的长度。
您可能想要考虑如何处理[ -~]
之外的字符。 您可能还想使用已实现该功能的库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.