9

我们正试图摆脱 boost::regex ,它的性能很糟糕。根据这个基准,Oniguruma是最好的整体。

我们有多个正则表达式(并且总是在变化),我们应用于从中等(100 个字符)到巨大(1k 个字符)的字符串......所以这是一个非常异构的环境。

你们中有人成功使用过它吗?您是否建议选择 PCRE 或 RE2 等更“标准”的产品?

谢谢 !

4

2 回答 2

9

这两种实现(FSA 和 BT)具有完全不同的行为,您可以在右侧的列(电子邮件)中看到这些行为。

oniguruma 通常很快,但如果您对特定的正则表达式“不走运”,则可能会运行缓慢。那是因为它是一种回溯算法。

相比之下,虽然 re2 通常慢一点,但它没有相同的风险 - 它的时间永远不会[*] 以相同的方式爆炸(它没有最坏情况下的指数行为)。

所以这取决于细节。如果你确信你的正则表达式是安全的,或者愿意检测并中止慢匹配,那么 oniguruma 是有意义的。但就我个人而言,我倾向于为 re2 的安全性支付更多(不多)。

有关这方面的更多信息,请参阅http://swtch.com/~rsc/regexp/regexp1.html(由 re2 作者提供)。

[*] 好吧,也许永远不会太强大。对于某些正则表达式,我认为在某些情况下它必须依靠 BT 方法(可能涉及匹配以前的匹配和前瞻)。但在大多数正则表达式上它仍然更安全。

于 2012-08-16T23:53:14.357 回答
6

我已经对以下库进行了基准测试:

  • 促进
  • 重2
  • 鬼鬼座

基准测试包括执行一系列测试,这些测试在非常异构的正则表达式上大量使用正则表达式(分组、不分组、长的(484 个字符)、短的、管道、\?、*、. 等)。应用于从几个字符到大约 8k 个字符的文本。

每次计算正则表达式匹配时,我都会存储正则表达式并增加一个毫秒计数器,以累积计算正则表达式所花费的时间(称为多次)。

以下是每个库的所有正则表达式所花费的总时间:

  • 提升:98840 毫秒
  • 回复 2:51197 毫秒
  • 鬼魂:16095 毫秒
  • re2(无 CAPUTRE* 见下文)):16162 毫秒

*我们(几乎)总是想在正则表达式中捕获组的内容,而 re2 在捕获组时表现得很糟糕见这里)。在上面的结果中你看不到那么多,因为当组不能被捕获时,它表现得很好。例如在这个正则表达式上(执行了很多次):

^((?:https?://)?(?:[a-z0-9\-]{1,63}\.)+(?:[a-z0-9\-]{1,63}))(?:[^\?]*).*$

以下是每个库的结果:

  • 提升:140 毫秒
  • 回复 2:5663 毫秒
  • 鬼魂:53 毫秒
  • re2(无捕获):37 毫秒。

查看 re2 从 5663 ms 到 37 ms 的下降。

tl;博士

所以我的结论是,就我们的使用而言,Oniguruma 显然更胜一筹。

但如果你不需要捕获组,re2 是更好的选择,因为我发现它的 API 更易于使用。

于 2012-08-22T12:36:17.497 回答