regex 如何在Java中减少正则表达式匹配过程的CPU使用?

67up9zun  于 2023-05-23  发布在  Java
关注(0)|答案(1)|浏览(172)

我最近在一个与正则表达式匹配相关的项目中遇到了一个问题,它在运行时使CPU使用率高达90%。我怀疑正则表达式优化是否足够公平,因为在我的代码中,它在并发调用下存在性能问题。
例如,我调用这个方法100次并发,在运行时,我的CPU使用率上升到92%一毫秒。
下面是我的代码示例:

String BUY_PATTERN =".*\\b(purchase)\\b.*";

private static boolean isMatchPattern(String pattern, String text) {
     return text.matches(BUY_PATTERN);
}

我应该做些什么来减少CPU的使用?你能推荐一些性能更好的正则表达式模式来为我做同样的工作吗?
我也读过这篇关于回溯的文章,但是用低回溯重写正则表达式很困难。
谢谢!
https://medium.com/javarevisited/a-regular-expression-makes-the-cpu-soar-to-100-72036a4b0771

n6lpvg4x

n6lpvg4x1#

你可以做一些改变。
您可以通过创建可重用的对象来大大减少CPU消耗。

public class Example {
    Pattern pattern = Pattern.compile("\\bpurchase\\b");
    Matcher matcher;

    private boolean isMatchPattern(String text) {
        matcher = pattern.matcher(text);
        return matcher.find();
    }
}

在后台,每次调用String.matches时,都会创建一个新的PatternMatcher对象。
为了解决这个问题,您可以在类中创建PatternMatcher字段。
然后,从isMatchPattern方法中访问这些字段。
此外,对于正则表达式模式,不需要捕获文本“purchase”,因此可以删除括号。
此外,Pattern模式的上下文是不一致的;它应该在文本中的任何地方。
String.matches调用相反,它需要整个参数匹配。
因此,您不需要开始和结束.*,因为它们是冗余的。
关于使用String.indexOfString.contains
如果您需要进行单词边界检查,那么从惯用方法的Angular 来看,这是不可能的,因为您必须进行多个调用。
如果你不需要检查,那么这将是一条路要走。
作为最终的解决方案,您可以创建一个字符数组for循环,这或多或少是Matcher类所做的。

相关问题