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

时间:2010-04-06 13:11:27

标签: java

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

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

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

在对应用程序进行概要分析时,该程序在此功能中花费大约58%的时间,替换时总共占47%,在replaceAll中占11%。

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

提前致谢!

8 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

Apache Commons LangescapeHtml类中有一个非常有效的StringEscapeUtils方法。

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

我没有任何方便的基准测试,但如果这些东西位于代码的关键路径上,那么您将会使用这种现成的,更快的解决方案。

答案 3 :(得分:1)

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

我建议您修改算法,以便不再执行N replace次操作(每次都需要扫描字符串),而只扫描列表一次:

//psuedocode
Map<Char, String> replacements = new HashMap<String, String>();
replacements.put("&", "&amp;");
replacements.put(">", "&gt;");
...
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 LangStringEscapeUtils,以便快速实现转义HTML实体。

答案 6 :(得分:0)

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

显然,你可以通过逐个字符地迭代来编写更快的代码。可能首先计算出确切的长度。

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

答案 7 :(得分:0)

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

HTML代码的unescape操作可以这样完成:

final String unescapedText = HtmlEscape.unescapeHtml(escapedText);