7

我正面临两难境地。我正在解析一个字符串,可以做

s.matches(regex)

或者我可以

s.startsWith(..) && s.endsWith(..)

正如您已经意识到的那样,它不是一个复杂的正则表达式,两种情况都可以。这个想法是,字符串可能很长(数百个字符),所以我希望最大限度地提高效率。什么工作如何更好地适应这个问题?

4

3 回答 3

7

这是一个非常粗略的基准,可以给你一个想法。使其适应您的用例,为您提供更相关的结果。startsWith 和 endsWith 更快。1000000 次运行后的结果:

未编译模式 1091ms

编译模式 745ms

开始时间/结束时间为 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));

}

}
于 2013-11-06T08:54:26.780 回答
5

请注意,如果末尾的字符串是起始字符串的后缀,两种方法可能会报告不同的结果:

^start.*art$

不匹配

"start"

尽管

"start".startsWith("start") && "start".endsWith("art")

将是真的。

于 2013-11-06T09:35:23.547 回答
1

确实,对于小弦乐而言,差异是存在的并且很明显。使用模式编译正则表达式的版本确实会带来一些增强,但毫无疑问,当匹配很容易时,这是最糟糕的主意。

感谢大家。

于 2013-11-06T09:30:04.363 回答