Java的String.replace()与String.replaceFirst()与homebrew

时间:2010-10-01 21:05:14

标签: java regex string performance replace

我有一个正在进行大量文本处理的课程。对于每个字符串,其长度为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"));

这样我放弃第一次替换(而不是遍历整个字符串),我正在使用字面正则表达式,我不是在做重新编译每一次迭代。

那么,哪种表现最好?

3 个答案:

答案 0 :(得分:3)

  

那么,哪种表现最好?

测量它! ; - )

ETA:由于两个字的答案听起来无可挽回,我会稍微详细说明一下。 “测量并告诉我们......”因为可能有一些关于你引用的各种方法的表现的一般经验法则(好的,全部),但我不知道它。正如对这个答案的一些评论所提到的那样,即便如此,不同的方法也很有可能被应用程序环境所淹没。所以,测量它 in vivo 并关注它,如果这是一个真正的问题。 (让我们知道它是怎么回事......)

答案 1 :(得分:2)

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

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

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

接下来实现一些简单的替代方案并试用它们。其中一个足够好吗?完成!

除了您的想法,您可以尝试将搜索词连接到单个正则表达式(例如“(foo | baz)”),使用Matcher.find(int)查找每个匹配项,使用HashMap来查找替换字符串和StringBuilder以从输入字符串子串和替换构建输出String。 (好吧,这不是完全无关紧要的,它取决于模式/匹配器处理交替有效......我不确定是这样。但这就是为什么你应该仔细比较候选人。)

在(IMO不太可能)事件中,一个简单的替代方案没有削减它,this wikipedia page有一些线索可以帮助您实现自己的有效匹配/替换。

答案 2 :(得分:0)

当你问一个问题并获得一堆建议告诉你做了大量的工作并为自己解决问题时,难道不是很令人沮丧吗?!

我说使用replaceAll();

(我不知道它是否确实是最有效的,我只是不希望你觉得你在这个问题上浪费了你的钱并且什么都没有。)

[编辑] PS。之后,您可能想要测量它。

[编辑2] PPS。 (并告诉我们你找到了什么)