我有一个像这样的字符串:
/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/