【问题标题】:Java's String.replace() vs. String.replaceFirst() vs. homebrewJava 的 String.replace() vs. String.replaceFirst() vs. homebrew
【发布时间】:2011-04-20 01:46:08
【问题描述】:

我有一个类正在做大量的文本处理。对于每个长度为 100->2000 个字符的字符串,我执行 30 种不同的字符串替换。

例子:

string modified;
for(int i = 0; i < num_strings; i++){
 modified = runReplacements(strs[i]);
 //do stuff
}

public runReplacements(String str){
  str = str.replace("foo","bar");
  str = str.replace("baz","beef");
  ....
  return str;
}

'foo'、'baz' 和所有其他“目标”预计只会出现一次并且是字符串文字(不需要实际的正则表达式)。

如你所想,我很关心性能:)

鉴于此,

  • replaceFirst() 似乎是一个糟糕的选择,因为它不会使用 Pattern.LITERAL 并且会执行不需要的额外处理。

  • replace() 似乎是一个糟糕的选择,因为它会遍历整个字符串以寻找要替换的多个实例。

此外,由于我的替换文本每次都相同,因此我编写自己的代码似乎是有意义的,否则 String.replaceFirst()String.replace() 将在后台每次执行 Pattern.compile。认为我应该编写自己的代码,这是我的想法:

  • 对每个需要的文字替换执行Pattern.compile()仅一次(无需每次都重新编译)(即 p1 - p30)

  • 然后对每个 pX 执行以下操作:p1.matcher(str).replaceFirst(Matcher.quoteReplacement("desiredReplacement"));

这样我在第一次替换时就放弃了(而不是遍历整个字符串),我使用的是 literalregex,我没有做每次迭代都重新编译。

那么,哪个性能最好?

【问题讨论】:

    标签: java regex string performance replace


    【解决方案1】:

    那么,哪个性能最好?

    测量它! ;-)

    ETA:由于两个词的答案听起来很尖刻,所以我会稍微详细说明一下。 “测量它并告诉我们......”因为可能有一些关于您引用的各种方法的性能的一般经验法则(好的方法,所有),但我不知道。正如这个答案中的几个 cmets 所提到的,即便如此,不同的方法很可能会被应用程序环境淹没。因此,在体内对其进行测量,如果这是一个真正的问题,请关注这一点。 (让我们知道进展如何......)

    【讨论】:

    • 该死的,打败我。 @jonathon,除非您知道自己有性能问题,否则您不会遇到性能问题。
    • 并在你的应用程序的上下文中测量它做它应该做的事情,这似乎是很多工作,但它很容易被任何网络流量的 db 调用的噪音所迷失
    【解决方案2】:

    首先,通过简单的匹配/替换来运行和分析您的整个应用程序。这可能会告诉你:

    • 您的应用程序已经运行得足够快,或者
    • 您的应用程序大部分时间都在做其他事情,因此不值得优化匹配/替换代码。

    假设您已确定匹配/替换是一个瓶颈,请为自己编写一个小型基准测试应用程序,让您可以在代表性输入数据上测试候选算法的性能和正确性。包含可能导致问题的“极端情况”输入数据也是一个好主意;例如对于您示例中的替换,包含序列“bazoo”的输入数据可能是一个极端情况。在性能方面,请确保避免 Java 微基准测试的陷阱;例如JVM 预热效果。

    接下来实施一些简单的替代方案并尝试一下。其中之一是否足够好?完成!

    除了您的想法之外,您还可以尝试将搜索词连接成单个正则表达式(例如 "(foo|baz)" ),使用 Matcher.find(int) 查找每个匹配项,使用 HashMap 查找替换字符串和一个 StringBuilder 从输入字符串子字符串和替换构建输出字符串。 (好吧,这并不完全是微不足道的,它依赖于 Pattern/Matcher 有效地处理交替......我不确定是不是这样。但这就是为什么你应该仔细比较候选人的原因。)

    如果(IMO 不太可能)一个简单的替代方案无法解决问题,this wikipedia page 有一些线索可以帮助您实现自己的高效匹配/替换器。

    【讨论】:

      【解决方案3】:

      当您提出问题并得到一堆建议告诉您做大量工作并自己解决时,这不是令人沮丧吗?!

      我说使用 replaceAll();

      (我不知道它是否确实是最有效的,我只是不想让你觉得你在这个问题上浪费了你的钱却一无所获。)

      [编辑] PS。之后,您可能需要对其进行测量。

      [编辑 2] 聚苯乙烯。 (并告诉我们你发现了什么)

      【讨论】:

        猜你喜欢
        • 2013-05-08
        • 2014-04-16
        • 1970-01-01
        • 2012-10-20
        • 2012-06-21
        • 2014-07-05
        • 1970-01-01
        • 1970-01-01
        • 2017-04-24
        相关资源
        最近更新 更多