我有一个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中出现瓶颈,而不是在我的代码中? (或者我替换错了?)
提前致谢!
答案 0 :(得分:8)
对于html转义,您可以使用StringEscapeUtils.escapeHtml(input)
中的commons-lang。据推测,它可以更有效地实施。
答案 1 :(得分:3)
这当然不是进行大量替换的最有效方法。由于字符串是不可变的,因此每个.replace()都会导致构造一个新的String对象。对于您给出的示例,每次调用此函数都会导致临时创建6个String对象。
考虑到您提供的示例,最简单的解决方案是使用现有的库函数进行HTML实体编码。 Apache commons StringEscapeUtils是一种选择。另一个是HTMLEntities
答案 2 :(得分:1)
Apache Commons Lang在escapeHtml
类中有一个非常有效的StringEscapeUtils
方法。
它相当聪明,并且不会以您描述的方式使用字符串替换,而是遍历字符,在找到它们时用适当的实体替换字符。
我没有任何方便的基准测试,但如果这些东西位于代码的关键路径上,那么您将会使用这种现成的,更快的解决方案。
答案 3 :(得分:1)
每次调用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();
}
答案 4 :(得分:1)
使用http://commons.apache.org/lang/更容易,更标准。这很简单。
答案 5 :(得分:0)
使用多种替换方法的方法可能会很慢。
查看Apache Commons Lang的StringEscapeUtils,以便快速实现转义HTML实体。
答案 6 :(得分:0)
String.replace
的一般算法有点复杂,但不应该那么糟糕。看看代码,它实际上是使用正则表达式实现的,所以不会快 - ick。
显然,你可以通过逐个字符地迭代来编写更快的代码。可能首先计算出确切的长度。
您可能想要考虑如何处理[ -~]
之外的字符。您可能还想使用已实现该功能的库。
答案 7 :(得分:0)
对于休闲读者,Html转义字段中有一个新玩家:unbescape。
HTML代码的unescape操作可以这样完成:
final String unescapedText = HtmlEscape.unescapeHtml(escapedText);