2010-10-01 100 views
5

我有一个类正在做很多文本处理。对于每个字符串(长度为100到2000个字符),我执行30个不同的字符串替换。Java的String.replace()与String.replaceFirst()与自制软件

例子:

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; 
} 

“富”,“巴兹”,和所有其他“目标”,预计只出现一次,并且是字符串(不需要实际的正则表达式)。

正如你可以想像,我关心的性能:)

鉴于此,

  • replaceFirst()似乎一个不错的选择,因为它不会使用Pattern.LITERAL,并会做额外的处理与工作不” t需要。

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

此外,由于我的替换文本是相同的,每次,它似乎很有道理,我以其他方式写我自己的代码String.replaceFirst()String.replace()会做背景中的Pattern.compile每一次。想,我应该写我自己的代码,这是我的想法:

  • 的期望每个面值替换(无需重新编译每一次)执行Pattern.compile()只有一次(即P1 - P30)

  • 然后做各的pX如下:p1.matcher(str).replaceFirst(Matcher.quoteReplacement("desiredReplacement"));

这样,我放弃了在第一次更换船(而不是遍历整个字符串),和我使用文字正则表达式,我没有重新编译每一个迭代。

那么,哪个性能最好?

回答

3

那么,哪个性能最好?

衡量它! ;-)

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

+1

该死的,打我吧。 @jonathon,在你知道你有性能问题之前,你没有性能问题。 – dty 2010-10-01 21:08:58

+2

并在您的应用程序的上下文中进行测量,它可能看起来像很多工作,但它可能很容易在任何网络流量的db调用中丢失 – 2010-10-01 21:14:53

2

首先,运行并通过简单的匹配/替换来分析整个应用程序。这可能表明您:

  • 您的应用程序已经运行速度不够快,或
  • 你的应用程序花费大部分时间做别的事情,所以优化匹配/替换代码是不值得的。

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

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

除了你的想法,你可以尝试串联搜索词成一个单一的正则表达式(如“(FOO |巴兹)”),使用Matcher.find(int)发现每次出现,用HashMap来查找替换字符串和一个StringBuilder从输入字符串子字符串和替换构建输出字符串。 (好吧,这并不是完全无关紧要的,它依赖于模式/匹配器有效地处理替换项......我不确定是这种情况,但这就是为什么你应该仔细比较候选项。)

在( IMO不太可能)事件,一个简单的选择不会削减它,this wikipedia page有一些可能会帮助你实现你自己的高效匹配/替代品的线索。

0

如果你问一个问题,并得到一堆建议,告诉你做了大量的工作,并找出自己的想法是不是很令人沮丧?

我说使用replaceAll();

(我不知道,如果它确实是最有效的,我只是不想让你觉得你浪费在这个问题上你的钱,什么都没有。)

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

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