出于性能原因,Java String.split传入预编译的正则表达式

Woo*_*Moo 17 java regex performance

正如问题所述,给出了以下代码:

public class Foo
{
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = test.split(" ");
   }
}
Run Code Online (Sandbox Code Playgroud)

是否可以在split函数中预编译该正则表达式:

public class Foo
{  
   Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = test.split(pattern);
   }
}
Run Code Online (Sandbox Code Playgroud)

rge*_*man 22

对的,这是可能的.另外,make patternstatic,静态方法main可以访问它.

public class Foo
{  
   private static Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = pattern.split(test);
   }
}
Run Code Online (Sandbox Code Playgroud)

根据该文档splitString中的方法,你可以使用字符串的split或图案的split,但字符串的split编译一个Pattern并调用它的split方法,所以使用Pattern预编译正则表达式.

  • 是的,`Pattern#split(string)` 大约快了 25%。请参阅 Oracle 的性能基准(幻灯片 72)https://shipilev.net/talks/joker-Oct2014-string-catechism.pdf (2认同)

mic*_*l_s 7

不 - 我认为那是个坏主意!

仔细查看拆分方法的源代码 - 如果字符串只有一个字符(并且不包含正则表达式特殊字符),则实现了一个快捷方式

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) ||
Run Code Online (Sandbox Code Playgroud)

所以 - split(" ") 应该快很多。

另一方面,当使用正则表达式时,让它们成为静态最终成员总是一个好主意。

编辑:

String.split 的源代码 JDK1.7 和 OpenJDK 7 似乎相同 - 自己看看: 第 2312 行。

所以 - 对于更复杂的模式(例如 1 个或多个空格):

   static final Pattern pSpaces = Pattern.compile("[ ]+");
Run Code Online (Sandbox Code Playgroud)


Eng*_*uad 5

public class Foo
{  
   private static final Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = pattern.split(test);
   }
}
Run Code Online (Sandbox Code Playgroud)