转载记录
最近看了阿里巴巴的java代码开发规范发现处理正则表达式的时候必须要预编译,可以有效加快正则匹配速度。
错误案例
现象描述: Java5的正则表达式的实现可能会导致JVM的崩溃;在递归处理上性能极度低下
错误分析
错误原因: 1、Java5 自身带的实现,没有执行事实上perl标准,导致很多书写方式上和perl的表达不一样, 导致学习成本高 2、已经明确的观察到,Java5的实现可能会导致JVM的崩溃。 3、在深度递归处理下性能很差 4、正则表达式在运行期编译很耗费性能,我们可以看Perl5Compiler().compile方法有差不多200行的代码,都是在做编译工作。
以下是一个错误的例子:每次需要用正则去匹配的时候,都需要把pattern编译一遍,导致性能低下
private static final String LOGINID_REGEX = "^[a-zA-Z]+[a-zA-Z0-9]+"; .... if (!Pattern.compile(LOGINID_REGEX).matcher(resultStr).find()) { ... }
正确用法
正确用法: 1. 建议使用ORO库来处理这类问题。 2. 不要使用大规模长度的表达式, 比如根据配置文件的字符串, 拼接成一个非常长的表达式。 这个会导致匹配性能非常的低下。 3. 表达式一定要求是预先编译的, 这个编译过程是非常具有消耗性能的。 4. 如果一些是非频繁的使用的表达预先编译可能在代码的处理上会有点麻烦, 不过, ORO提供给我们一个比较好的util实现:Perl5Util, 他能在cache住一些经常被使用的表达式。 不过大约就是20个样子。 更多http://sdh5724.javaeye.com/blog/277352
private final static Pattern pattern = new Perl5Compiler().compile("^\\d+$", '''Perl5Compiler.READ_ONLY_MASK'''); //请注意,由于Pattern本身不是线程安全的,只有加了READ_ONLY_MASK的编译参数才能用于共享使用,否则会出现并发访问的问题,导致错误结果 public void mach(){ PatternMatcher matcher = new Perl5Matcher(); if (matcher.matches(str, pattern)) { …… } }