java - 编译还是不编译模式?

标签 java regex string performance

我正在开发脚本代码生成器。我创建了一个模板脚本文件,其中包含一些参数和占位符的占位符,在生成过程中应将其替换为实际值。替换是在循环内执行的。生成器的性能非常重要(目前在 Java 7 上)。我的困境如下:

做这样的事情:

private final String PHOLDER_SECT = "#__PHOLD_SECT__#";
private final String PARAM_PID    = "__param_pid";
private final String PARAM_NAME   = "__param_name";
private final String PARAM_DESC   = "__param_desc";
...
for (int i = 0; i < sectionCount; i++) {

    // do something here...
    masterTmpl[i] = masterTmpl[i].replace(PHOLDER_SECT, someSectionCode);
    // something else here...
    masterTmpl[i] = masterTmpl[i].replace(PARAM_DESC, desc)
                                 .replace(PARAM_NAME, name)
                                 .replace(PARAM_PID,  pid)
    ...
}

或者类似的东西(重点是所有占位符都是编译模式):

private final Pattern regexSect = Pattern.compile("#__PHOLD_SECT__#", Pattern.LITERAL);
private final Pattern regexPid  = Pattern.compile("__param_pid",      Pattern.LITERAL);
private final Pattern regexName = Pattern.compile("__param_name",     Pattern.LITERAL);
private final Pattern regexDesc = Pattern.compile("__param_desc",     Pattern.LITERAL);
...
for (int i = 0; i < sectionCount; i++) {

    // do something here...
    masterTmpl[i] = this.regexSect.matcher(masterTmpl[i]).replaceAll(Matcher.quoteReplacement(someSectionCode));
    // something else here...
    masterTmpl[i] = this.regexDesc.matcher(masterTmpl[i]).replaceAll(Matcher.quoteReplacement(desc));
    masterTmpl[i] = this.regexName.matcher(masterTmpl[i]).replaceAll(Matcher.quoteReplacement(name));
    ...
}

我知道我可以衡量执行情况等,但我希望得到一个答案来解释模式编译在这种特殊情况下的(不)重要性......

最佳答案

这段代码可能要快得多,因为它在一次搜索中找到模式的出现(而不是每个模式一个);最重要的是,所有替换都在一次传递中完成,而不是每个模式需要一次传递。由于复制和内存开销,构建许多字符串有点昂贵 - 这仅在最后一行构建一个完全替换的字符串。

    public static String replaceMany(String input, 
            Map<String, String> replacements) {
        // build a composite pattern for all replacement keys
        StringBuilder sb = new StringBuilder();
        String prefix = "";
        for (String k : replacements.keySet()) {
            sb.append(prefix).append(Pattern.quote(k));
            prefix = "|";
        }
        Pattern p = Pattern.compile(sb.toString());
        // replace in single loop
        Matcher m = p.matcher(input);
        StringBuffer output = new StringBuffer();
        while (m.find()) {
            // inspired by http://stackoverflow.com/a/948381/15472
            m.appendReplacement(output, "");
            output.append(replacements.get(m.group(0)));
        }
        m.appendTail(output);
        return output.toString();
    }

关于java - 编译还是不编译模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31270979/

相关文章:

java - 确定给定的单词字符串是否包含大于 5 个字母的单词

java - 使用循环的初学者二十一点游戏

java - 从未排序数组构建最大堆会遵循二叉树属性吗?

java - 如果流没有手动关闭,什么时候关闭?

java - 管理 struts 2 中单一操作的不同方法

php - 如何从 Twitter 主题标签中删除#?

jquery - 在 jQuery 验证引擎中添加自定义正则表达式验证

JavaScript RegExp 可选捕获组

c - 为什么 strcmp 失败了?

python - str.contains() 的用法应用于 pandas 数据框