首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pattern.split比String.split慢

Pattern.split比String.split慢
EN

Stack Overflow用户
提问于 2015-04-01 14:12:15
回答 3查看 1.2K关注 0票数 9

有两种方法:

代码语言:javascript
复制
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);

}

我这样测试他们的主要方法:

代码语言:javascript
复制
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),直接调用只消耗了使用预先构造的模式对象的一半时间。

有人能告诉我为什么会发生这种事吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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行。

代码语言:javascript
复制
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。

票数 5
EN

Stack Overflow用户

发布于 2015-04-01 14:38:58

这是String.split行为的变化,这是在Java 7中发生的。这就是我们在 in 7u40

代码语言:javascript
复制
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

代码语言:javascript
复制
public String[] split(String regex, int limit) {
    return Pattern.compile(regex).split(this, limit);
}
票数 2
EN

Stack Overflow用户

发布于 2015-04-01 14:29:00

我认为这只能通过JIT优化来解释,String.split内部的实现如下所示:

代码语言:javascript
复制
Pattern.compile(regex).split(this, limit);

当它在String.class中运行时,它的工作速度更快,但是当我在测试中使用相同的代码时:

代码语言:javascript
复制
    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)一样

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29393086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档