正则表达式VS包含.最棒的表演?

Mik*_*ike 27 java regex

我想在java中比较不同模式的URI字符串,我想要尽可能快的代码.

我应该使用:

if(uri.contains("/br/fab") || uri.contains("/br/err") || uri.contains("/br/sts")
Run Code Online (Sandbox Code Playgroud)

或类似的东西:

if(uri.matches(".*/br/(fab|err|sts).*"))
Run Code Online (Sandbox Code Playgroud)

请注意,我可以使用更多uri,并且经常调用此方法.

我的选择之间最好的答案是什么?

Jon*_*eet 26

如果您要使用正则表达式,请预先创建它并重用相同的Pattern对象:

private static final Pattern pattern = Pattern.compile(".*/br/(fab|err|sts).*");
Run Code Online (Sandbox Code Playgroud)

你真的需要两端的".*"吗?如果你使用的话我不希望它被要求Matcher.find().

哪个更快?最简单的方法是根据一些样本数据对其进行测量 - 尽可能使用尽可能逼真的样本.(最快的解决方案可能很好地依赖于

您是否已经确定这是一个瓶颈?如果你已经测量了足够的代码以发现它是一个瓶颈,我很惊讶你们还没有尝试过两者.如果您还没有确认这是一个问题,那么在担心"最快的代码可能"之前,这是首先要做的事情.

如果它不是瓶颈,我会亲自选择非正则表达版本,除非你是一个正则表达式的瘾君子.正则表达式非常强大,但也很容易出错.

  • 让我们说这是一个理论问题.优化可能很有趣,即使它不是瓶颈. (6认同)
  • @Robert:可以,但这可能取决于实际数据.您可以提出一个测试,显示一种方法更快 - 然后使用OP的真实数据,您可以得到另一个答案.我认为,在您认为需要"最快的代码可能"之前,了解应该检查瓶颈的实际问题更为重要. (2认同)

Mik*_*ike 16

我做了一个测试,使用包含更快.正如Ewan Todd所说,他们都足够快,不会那么烦.

  • 如果你必须这样做数万亿次,那很重要:-) (3认同)

小智 7

两者都足够快,但包含速度更快。事实:约2000万次作战与约100万次作战

使用以下jmh代码进行测试

@State(Scope.Benchmark)
public class Main {

  private String uri = "https://google.com/asdfasdf/ptyojty/aeryethtr";

  @Benchmark
  @Warmup(iterations = 5)
  @Measurement(iterations = 5)
  @Fork(value = 1, warmups = 0)
  public void initContains() throws InterruptedException {
    if (uri.contains("/br/fab") || uri.contains("/br/err") || uri.contains("/br/sts")) {}
  }

  @Benchmark
  @Warmup(iterations = 5)
  @Measurement(iterations = 5)
  @Fork(value = 1, warmups = 0)
  public void initMatches() throws InterruptedException {
    if (uri.matches(".*/br/(fab|err|sts).*")) {}
  }

  public static void main(String[] args) throws Exception {
    org.openjdk.jmh.Main.main(args);
  }
}
Run Code Online (Sandbox Code Playgroud)

结果

# Run complete. Total time: 00:00:37

Benchmark           Mode  Cnt         Score         Error  Units
Main.initContains  thrpt    5  21004897.968 ± 1987176.746  ops/s
Main.initMatches   thrpt    5   1177562.581 ±  248488.092  ops/s
Run Code Online (Sandbox Code Playgroud)


Ewa*_*odd -14

他们的速度都足够快,在你意识到之前就结束了。我会选择您可以更轻松阅读的一本。

  • 没有回答OP提出的问题。投反对票。 (13认同)
  • 非常糟糕的答案。您可以进行数千或数百万次迭代的性能测试。 (12认同)
  • 我同意你的观点,在大多数情况下,这没有什么区别,但我也想知道哪一个最快。我曾经在这个应用程序中工作过,它必须对超过 20kk 的条目(如文件或维基百科页面)执行相同的过程,我们能获得的每一毫秒的性能都是成功的关键,因为整个“扫描”需要长达 15 天的时间。 (10认同)
  • 对于人眼来说足够快并不能回答 OP'e 的问题。代码并不总是为人类阅读而编写的。这个问题是针对性能的 (2认同)
  • 需要更具体、有效的证据来证明你的观点。投反对票。 (2认同)