我面临一个两难的境地。 我正在解析一个字符串,可以选择
s.matches(regex)
或者我可以做。
s.startsWith(..) && s.endsWith(..)
正如您已经意识到的那样,这不是一个复杂的正则表达式,两种情况都可以工作。 思路是,字符串可能非常长(数百个字符),因此我希望最大化效率。 哪种方法适用于问题并更好?
我面临一个两难的境地。 我正在解析一个字符串,可以选择
s.matches(regex)
s.startsWith(..) && s.endsWith(..)
正如您已经意识到的那样,这不是一个复杂的正则表达式,两种情况都可以工作。 思路是,字符串可能非常长(数百个字符),因此我希望最大化效率。 哪种方法适用于问题并更好?
这里有一个相当粗略的基准测试,可供参考。将其调整到您的用例以获得更相关的结果。
startsWith()
和endsWith()
速度更快运行100万次后的结果:
- 未编译的模式: 1091 毫秒 - 已编译的模式: 745 毫秒 - startsWith() / endsWith(): 24 毫秒
public class TestRegex {
String regex = "^start.*end$";
Pattern p = Pattern.compile(regex);
String start = "start";
String end = "end";
String search = start + "fewbjlhfgljghfadsjhfdsaglfdhjgahfgfjkhgfdkhjsagafdskghjafdkhjgfadskhjgfdsakhjgfdaskhjgafdskjhgafdsjhkgfads" + end;
int runs = 1000000;
@Test
public final void test() {
// Init run
for (int i = 0; i < runs; i++) {
search.matches(regex);
}
for (int i = 0; i < runs; i++) {
p.matcher(search).matches();
}
for (int i = 0; i < runs; i++) {
search.startsWith(start);
search.endsWith(end);
}
// Timed run
Stopwatch s = Stopwatch.createStarted();
for (int i = 0; i < runs; i++) {
search.matches(regex);
}
System.out.println(s.elapsed(TimeUnit.MILLISECONDS));
s.reset();
s.start();
for (int i = 0; i < runs; i++) {
p.matcher(search).matches();
}
System.out.println(s.elapsed(TimeUnit.MILLISECONDS));
s.reset();
s.start();
for (int i = 0; i < runs; i++) {
search.startsWith(start);
search.endsWith(end);
}
System.out.println(s.elapsed(TimeUnit.MILLISECONDS));
}
}
^start.*art$
"start"
"start".startsWith("start") && "start".endsWith("art")
将会是真的。
实际上,即使是对于小字符串,它们之间的差异也是存在且明显的。使用模式的编译版本可以提高一些性能,但毫无疑问,在匹配容易的情况下,这是最糟糕的选择。
感谢大家。