有两种方法:
private static void normalSplit(String base){
base.split("\\.");
}
private static final Pattern p = Pattern.compile("\\.");
private static void patternSplit(String base){
//use the static field above
p.split(base);
}我这样测试他们的主要方法:
public static void main(String[] args) throws Exception{
long start = System.currentTimeMillis();
String longstr = "a.b.c.d.e.f.g.h.i.j";//use any long string you like
for(int i=0;i<300000;i++){
normalSplit(longstr);//switch to patternSplit to see the difference
}
System.out.println((System.currentTimeMillis()-start)/1000.0);
}直觉上,我认为String.split最终会打电话给Pattern.compile.split (在做了很多额外的工作后)去做真正的事情。我可以预先构造模式对象(它是线程安全的),并加快拆分速度。
但事实是,使用预先构造的模式是比直接调用String.split慢得多。我在它们上尝试了一个50字符长的字符串(使用MyEclipse),直接调用只消耗了使用预先构造的模式对象的一半时间。
有人能告诉我为什么会发生这种事吗?
发布于 2015-04-01 14:29:29
这可能取决于Java的实际实现。我使用的是OpenJDK 7,在这里,String.split确实调用Pattern.compile(regex).split(this, limit),但是只有当要拆分的字符串regex不止一个字符时才会调用Pattern.compile(regex).split(this, limit)。
有关源代码,请参见这里,第2312行。
public String[] split(String regex, int limit) {
/* fastpath if the regex is a
(1)one-char String and this character is not one of the
RegEx's meta characters ".$|()[{^?*+\\", or
(2)two-char String and the first char is the backslash and
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.count == 1 &&
// a bunch of other checks and lots of low-level code
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}当您被"\\."拆分时,它使用的是“快速路径”。也就是说,如果您使用的是OpenJDK。
发布于 2015-04-01 14:38:58
这是String.split行为的变化,这是在Java 7中发生的。这就是我们在有 in 7u40
public String[] split(String regex, int limit) {
/* fastpath if the regex is a
(1)one-char String and this character is not one of the
RegEx's meta characters ".$|()[{^?*+\\", or
(2)two-char String and the first char is the backslash and
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
{
//do stuff
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}这就是我们在有 in 6-b14
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}发布于 2015-04-01 14:29:00
我认为这只能通过JIT优化来解释,String.split内部的实现如下所示:
Pattern.compile(regex).split(this, limit);当它在String.class中运行时,它的工作速度更快,但是当我在测试中使用相同的代码时:
for (int i = 0; i < 300000; i++) {
//base.split("\\.");// switch to patternSplit to see the difference
//p.split(base);
Pattern.compile("\\.").split(base, 0);
}我得到的结果和p.split(base)一样
https://stackoverflow.com/questions/29393086
复制相似问题