Pattern.compile.split vs StringBuilder迭代和子串

时间:2013-06-14 14:04:13

标签: java string optimization split

我必须以最快的方式分割一个非常大的字符串,从我做的研究中我将其缩小到2种可能性:

1。Pattern.compile("[delimiter]").split("[large_string]");
2.遍历StringBuilder并致电substring

StringBuilder sb = new StringBuilder("[large_string]");
ArrayList<String> pieces = new ArrayList<String>();
int pos = 0;
int currentPos;
while((currentPos = sb.indexOf("[delimiter]", pos)) != -1){
    pieces.add(sb.substring(pos, currentPos));
    pos = currentPos+"[delimiter]".length();
}

任何帮助都表示赞赏,我会对它们进行基准测试,但我对理论部分更感兴趣:为什么一个比另一个更快。

此外,如果您有其他建议,请发布。

更新:正如我所说,我已经完成了基准测试,生成了5个字符串,每个字符串有32个字符,这些字符串放在由~~分隔的单个字符串中:

    令人惊讶的是,
  1. StringBuilder方法是最慢的,2.50-2.55 sec
  2. Pattern.compile.split以平均2.47-2.49 sec
  3. 排在第二位 Guava的
  4. Splitter是无可争议的赢家,其他人1.12-1.18 sec 一半平均(特别感谢 fge 谁建议了)
  5. 谢谢大家的帮助!

3 个答案:

答案 0 :(得分:3)

如果您的字符串很大,需要考虑的是是否制作了任何副本。如果您不使用StringBuilder但使用普通String#substring(from,to),那么 no 将复制该字符串的内容。将会有1个整个字符串的实例,只要至少有1个子字符串存在,它就会一直存在。

嗯......模式类的源代码显示split执行相同的操作,而StringBuilder的源显示为每个子字符串创建副本。

答案 1 :(得分:2)

如果这是固定模式,并且您不需要正则表达式,则可能需要考虑Guava's Splitter。它编写得很好,表现令人钦佩:

private static final Splitter SPLITTER = Splitter.on("myDelimiterHere");

另外,与.split()不同,你最终不会得到空字符串的令人讨厌的惊喜...(你必须传递一个负整数作为参数,以便它进行“真正的”分割)

您还会看到此类“.split()方法返回Iterable<CharSequence>;当字符串非常大时,它只会生成您要求它制作的必要副本!

答案 2 :(得分:1)

如果必须多次使用它,可以选择Pattern的静态对象。查看StringBuilder。方法indexOf也在做同样的事情,遍历所有字符。在内部,String.split()方法也使用Pattern来编译和拆分字符串。使用给定的方法,你应该有最好的表现......