我们正试图摆脱boost::regex,它的性能很糟糕。根据this benchmark,Oniguruma是整体上最好的。
我们有多个regexp(并且总是在变化),我们应用于从中等(100个字符)到巨大(1k个字符)的字符串……所以这是一个非常异质的环境。
你们中有没有人成功地使用过它?您是否建议使用更“标准”的产品,如PCRE或RE2?
谢谢!
发布于 2012-08-22 20:36:17
我用以下库做了一个基准测试:
该基准测试包括在非常异构的regexp上大量使用regexp的一系列测试(分组、不分组、长的(484个字符)、短的、管道、\?、*、.等)。适用于从几个字符到大约8k个字符的文本。
每次计算regexp匹配时,我存储regexp并递增一个毫秒计数器,该计数器累积计算regexp所用的时间(多次调用)。
下面是每个库在所有regexp上花费的总时间:
*我们(几乎)总是想在正则表达式中捕获组的内容,当re2捕获一个组(see here)时,它会执行可怕的。您在上面的结果中看不到那么多,因为当组不能被捕获时,它执行得很好。例如,在这个regexp上(执行了很多次):
^((?:https?://)?(?:[a-z0-9\-]{1,63}\.)+(?:[a-z0-9\-]{1,63}))(?:[^\?]*).*$
下面是每个库的结果:
查看re2从5663毫秒到37毫秒的下降。
tl;dr
所以我的结论是,对于我们的使用,Oniguruma显然是更好的。
但是如果你不需要捕获组,re2是一个更好的选择,因为我发现它的应用编程接口更容易使用。
发布于 2012-08-17 07:53:14
两种实现(FSA和BT)具有完全不同的行为,您可以在右栏(电子邮件)中看到。
oniguruma通常很快,但如果你在某个特定的regexp上“不走运”,可能会运行得很慢。这是因为它是一种回溯算法。
相比之下,虽然re2通常会慢一点,但它没有同样的风险-它的时间永远不会*以同样的方式爆炸(它没有最坏的情况下的指数行为)。
因此,这取决于细节。如果您确信您的正则表达式将是安全的,或者愿意检测并中止慢速匹配,那么oniguruma是有意义的。但就我个人而言,我倾向于为re2的安全性多花一点钱(不会多花多少钱)。
有关这方面的更多信息,请参阅http://swtch.com/~rsc/regexp/regexp1.html (由re2作者编写)。
*嗯,也许永远都不会太强烈。对于某些正则表达式,我认为在某些情况下(可能涉及匹配以前的匹配和先行查找),它必须依赖于BT方法。但在大多数正则表达式上仍然更安全。
https://stackoverflow.com/questions/11996988
复制相似问题