子字符串检测性能?

时间:2014-06-01 00:31:54

标签: java regex performance

我需要匹配一个子字符串,我想知道在匹配RegEx时哪一个更快?

if ( str.matches(".*hello.*") ) {
  ...
}


Pattern p = Pattern.compile( ".*hello.*" );
Matcher m = p.matcher( str );
if ( m.find() ) {
   ...
}

如果不需要regEx,我应该使用'包含' ?

if ( str.contains("hello") ) {
   ...
}

感谢。

2 个答案:

答案 0 :(得分:3)

尽管matches()和使用Matcher是相同的(matches()在其实现中使用了Matcher),但如果缓存并重用已编译的Pattern,则使用Matcher会更快。我做了一些粗略的测试,它将性能(在我的情况下)提高了400% - 改进取决于正则表达式,但总会有改进。

虽然我没有测试过,但我希望contains()能胜过任何正则表达式方法,因为算法要简单得多,而且你不需要正则表达式。


以下是测试包含子字符串的String的6种方法的结果,目标(“http”)位于标准60字符输入中的不同位置:

|------------------------------------------------------------|
| Code tested with "http" in the input  | µsec | µsec | µsec |
| at the following positions:           | start|   mid|absent|
|------------------------------------------------------------|
| input.startsWith("http")              |    6 |    6 |    6 |
|------------------------------------------------------------|
| input.contains("http")                |    2 |   22 |   49 |
|------------------------------------------------------------|
| Pattern p = Pattern.compile("^http.*")|      |      |      |
| p.matcher(input).find()               |   90 |   88 |   86 |
|------------------------------------------------------------|
| Pattern p = Pattern.compile("http.*") |      |      |      |
| p.matcher(input).find()               |   84 |  145 |  181 |
|------------------------------------------------------------|
| input.matches("^http.*")              |  745 |  346 |  340 |
|------------------------------------------------------------|
| input.matches("http.*")               | 1663 | 1229 | 1034 |
|------------------------------------------------------------|

两行选项是编译静态模式然后重用的地方。

答案 1 :(得分:1)

如果您在第二个代码段中使用m.match(),它们或多或少等效。 String.matches()规范了这一点:

  

调用str.matches(regex)形式的此方法会产生与表达式Pattern.matches(regex, str)

完全相同的结果

这又指定:

  

调用

形式的便捷方法
 Pattern.matches(regex, input);
     

的行为方式与表达式

完全相同
 Pattern.compile(regex).matcher(input).matches()
     

如果要多次使用某个模式,请将其编译一次   重复使用它比每次调用此方法更有效。

因此调用String.matches(String)本身不会带来性能优势,但存储模式(例如作为常量)并重用


如果您使用find,那么如果条款不及早匹配,那么matches会更有效率,因为find可能会继续关注。但findmatches没有执行相同的功能,因此性能比较没有实际意义。