java - 从性能角度来看,使用拆分或匹配正则表达式从字符串中提取子文本更好?

标签 java regex performance split

我有一个像这样的字符串:

/good/312321312/bad/3213122131

我必须从那里提取两组数字。 我考虑了两种解决方案:使用 split() 或简单地编写正则表达式来匹配数字。 性能方面更好的解决方案是什么? 如果您有任何其他建议,请告诉我。

最佳答案

由于创建新字符串意味着复制所有字符,因此 split 的隐式 substring 操作是这里最昂贵的方面。创建一个数组来保存所有字符串,并添加到其中,但与创建的字符串相比微不足道。不过,我们可以避免这两种情况。

static final Pattern NUMBER = Pattern.compile("\\d+");
public static void main(String[] args) {
    String s = "/good/312321312/bad/3213122131";

    long first = -1, second = -1;
    Matcher m = NUMBER.matcher(s);
    if(m.find()) {
        first = Long.parseLong(s, m.start(), m.end(), 10);
        if(m.find()) {
            second = Long.parseLong(s, m.start(), m.end(), 10);
        }
    }

    System.out.println(first + "\t" + second);
}

public static void main(String[] args) {
    String s = "/good/312321312/bad/3213122131";

    LongStream.Builder b = LongStream.builder();
    Matcher m = NUMBER.matcher(s);
    while(m.find()) b.add(Long.parseLong(s, m.start(), m.end(), 10));

    long[] result = b.build().toArray();

    System.out.println(Arrays.toString(result));
}

当性能很重要时,保留和重用已编译的 Pattern 实例非常重要,而不是使用像 String.split 这样的便捷方法操作后丢弃 Pattern 实例。

显然,只有当代码执行多次时这才重要。但当代码只执行一次时,它的性能无论如何都不重要。

Long.parseLong从 Java 9 开始就存在允许跳过 substring 操作的方法。但是,即使您在此处使用 Long.parseLong(m.group()),您也可以避免为非数字部分并保留尽可能短的临时字符串,这对优化器友好。

关于java - 从性能角度来看,使用拆分或匹配正则表达式从字符串中提取子文本更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76247049/

相关文章:

java - 这是使用软引用的正确方法吗

c# - 正则表达式 - 匹配但排除?

sql - 哪个 mysql select 更好/更快?

java - AddFolderListener 在某些设备中有效,但在其他设备中无效

java - 如何优化算法以能够在java中确定10位长素数

javascript - javascript 中的正则表达式在应该验证时未验证时遇到问题

python - 如何使用 Python Regex 提取特定字符串

python - 数据框子组中的滚动总和( Pandas )

regex - 如何为正则表达式集合找到 "minimal spanning set"?

java - 通过 Flyway 的 ODBC 连接