0

我必须以最快的方式拆分一个非常大的字符串,并且根据我所做的研究,我将其缩小到 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以 avg 排名第二2.47-2.49 sec
  3. Splitter番石榴是无可争议的赢家,平均1.12-1.18 sec 时间是其他人的一半(特别感谢fge提出的建议)

谢谢大家的帮助!

4

3 回答 3

3

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

嗯... Pattern 类的源代码细读表明 split 做同样的事情,而 StringBuilder 的源代码表明为每个子字符串制作了副本。

于 2013-06-14T14:12:39.420 回答
2

如果这是一个固定模式,并且您不需要正则表达式,您可能需要考虑Guava 的Splitter. 它写得非常好,表现令人钦佩:

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

此外,与 不同.split()的是,您不会在结尾处出现空字符串的令人讨厌的惊喜......(您必须传递一个负整数作为参数才能进行“真正的”拆分)

你还会看到这个类的.split()方法返回一个Iterable<CharSequence>; 当字符串真的很大时,它只会制作您要求它制作的必要副本!

于 2013-06-14T14:12:06.213 回答
1

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

于 2013-06-14T14:09:41.423 回答