Java Pattern.compile.split与StringBuilder迭代和子字符串
我必须以最快的方式拆分一个非常大的字符串,根据我所做的研究,我将其缩小为两种可能性: 1.Java Pattern.compile.split与StringBuilder迭代和子字符串,java,string,optimization,split,Java,String,Optimization,Split,我必须以最快的方式拆分一个非常大的字符串,根据我所做的研究,我将其缩小为两种可能性: 1.Pattern.compile(“[分隔符]”).split(“[大字符串]”) 2.遍历StringBuilder并调用substring StringBuilder sb = new StringBuilder("[large_string]"); ArrayList<String> pieces = new ArrayList<String>(); int pos = 0; i
Pattern.compile(“[分隔符]”).split(“[大字符串]”)代码>
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();
}
StringBuilder sb=newstringbuilder(“[large_string]”);
ArrayList片段=新的ArrayList();
int pos=0;
int-currentPos;
while((currentPos=sb.indexOf(“[delimiter]”,pos))!=-1){
添加(sb子字符串(位置,当前位置));
pos=currentPos+“[分隔符]”.length();
}
感谢任何帮助,我将对它们进行基准测试,但我更感兴趣的是理论部分:为什么一个比另一个快
此外,如果你有其他建议,请张贴
更新:正如我所说,我已经完成了基准测试,生成了500万个字符串,每个字符串有32个字符,这些字符串放在一个字符串中,由~
分隔:
StringBuilder
方法出人意料地是最慢的,平均速度为2.50-2.55秒
Pattern.compile.split
以2.47-2.49秒的平均值排在第二位
番石榴的《斯普利特》(Splitter)是无可争议的赢家,平均得分为1.12-1.18秒
是其他人的一半(特别感谢fge的建议)
谢谢大家的帮助 如果必须多次使用,则可以选择模式的静态对象。查看StringBuilder。indexOf方法也在做同样的事情,遍历所有字符。在内部,String.split()方法还使用模式编译和拆分字符串。使用给定的方法,您应该具有最佳的性能…如果您必须多次使用它,则可以选择模式的静态对象。查看StringBuilder。indexOf方法也在做同样的事情,遍历所有字符。在内部,String.split()方法还使用模式编译和拆分字符串。使用给定的方法,你应该有最好的性能…如果这是固定的模式,并且你不需要正则表达式,你可能需要考虑。这本书写得非常好,表现也非常出色:
private static final Splitter SPLITTER = Splitter.on("myDelimiterHere");
此外,与.split()
不同的是,您不会因为结尾的空字符串而感到意外。。。(必须将负整数作为参数传递,才能进行“实”拆分)
您还将看到这个类'.split()
方法返回一个Iterable
;当字符串非常大时,它只制作您要求它制作的必要副本 < P>如果这是固定模式,而不需要正则表达式,那么您可能需要考虑。这本书写得非常好,表现也非常出色:
private static final Splitter SPLITTER = Splitter.on("myDelimiterHere");
此外,与.split()
不同的是,您不会因为结尾的空字符串而感到意外。。。(必须将负整数作为参数传递,才能进行“实”拆分)
您还将看到这个类'.split()
方法返回一个Iterable
;当字符串非常大时,它只制作您要求它制作的必要副本如果你的字符串很大,需要考虑的是是否有任何拷贝。如果不使用StringBuilder,而是使用普通的String#子字符串(from,to)
,则不会复制字符串的内容。整个字符串将有一个实例,只要至少有一个子字符串存在,它就会一直存在
嗯。。。对模式类的源代码显示,Sype做了同样的事情,而StringBuilder的源显示了每个子串的副本。 如果您的字符串很大,要考虑的是是否有任何副本。如果不使用StringBuilder,而是使用普通的
String#子字符串(from,to)
,则不会复制字符串的内容。整个字符串将有一个实例,只要至少有一个子字符串存在,它就会一直存在
嗯。。。对Pattern类的源代码详细阅读表明split做了同样的事情,而StringBuilder的源代码表明为每个子字符串制作了副本。您是在正则表达式上拆分还是仅在文本字符串上拆分?我会使用split方法,因为我不太喜欢代码。我不确定StringBuilder方法在应用程序中是否会更快。也许在大型输入字符串上运行这两个选项,并比较它们的性能。@arshajii正则表达式,但我没有把它放在问题中,以避免它过于复杂化。这会产生不同:)@Bohemian Yes。我刚刚检查了Java 6和Java 7中的实现,它们都在StringBuilder.substring
中使用copy。您是在正则表达式上拆分还是只在文本字符串上拆分?我会使用split方法,只是因为我不喜欢太多的代码。我不确定StringBuilder方法在应用程序中是否会更快。也许在大型输入字符串上运行这两个选项,并比较它们的性能。@arshajii正则表达式,但我没有把它放在问题中,以避免它过于复杂化。这会产生不同:)@Bohemian Yes。我刚刚检查了Java 6和Java 7中的实现,它们都在StringBuilder中使用copy。子字符串
@fge最后的空字符串可以使用带有正确(意外)参数的标准拆分来处理。+1 thx作为替代方法,我将把它作为well@Bohemian我知道。。。但这种默认行为令人恼火,是的,但更糟糕的是,令人惊讶。它没有遵循“最小惊奇”的设计准则。因此存在着许许多多的问题。@Stephan Guava通常是一座金矿;)@结尾处的fge空字符串可以使用带有正确(意外)参数的标准拆分来处理。+1 thx作为替代,我将把它作为well@Bohemian我知道。。。但违约