将正则表达式编译为本机程序集会比PCRE或其他正则表达式引擎更快吗?

时间:2013-03-25 04:50:32

标签: c++ regex perl assembly pcre

我在考虑改进。我目前正在对日志文件进行大量的文本处理。

我并不是说PCRE是缓慢/快速的,或者是其他任何实现。

我写的语言主要是Perl。我知道它有一个强大的正则表达式引擎,我知道它比PCRE更具表现力。

我有这个想法,用C ++编写一个小的正则表达式引擎,可以将正则表达式编译为raw nasm。

我知道PCRE非常复杂,我的假设是我可以跳过PCRE在非必要处理方面所做的很多事情。而且我当然可以比Perl更快,因为它使用类似vm的操作码和各种可以被视为开销的东西。

我前段时间已经开始实施了。我不会在这里发布它,因为我没有任何问题,我可以将它带到最后并获得一个能够捕获的正则表达式引擎,能够解释+ {{1} } * ^,字符类(虽然我没有完成将正则表达式转换为汇编语言的部分)

这是一个好主意还是一个坏主意?在达到良好表现方面会出现什么问题?

tl; dr =>一个C ++迷你正则表达式引擎会产生本机组件比现有的正则表达式实现更快吗?

4 个答案:

答案 0 :(得分:6)

我认为这个问题的答案非常明显。理想情况下,是的,它可能是。但即使你非常聪明地做这种事情,也需要花费大量的开发工作才能达到这样的程度,在大多数情况下,你只比可用的库稍微好一点 - 甚至更长时间来处理所有的错误。所以没有多大意义。

答案 1 :(得分:6)

Perl的正则表达速度很快,但速度并不快。请参阅Russ Cox's analysis of Perl vs. Thompson-style regexp engines,了解性能差异,以及如何正确实施的理论。

如果你不想实现Thompson / Cox的方案,你应该考虑Ragel,一个非常快速的正则表达式处理器。 Ragel完成了构建高效自动机的艰苦工作,然后为目标编译器语言生成代码。它允许编译器完成将“转换为机器代码”的艰苦工作。

很可能是您正在考虑建造的发动机。

如果这些不够好,您应该在非常快速的流匹配器中追踪IBM最近的工作。我认为Davide Pasetto的论文可能是相关的。

答案 2 :(得分:3)

做一个基准测试。采用一个非常简单的正则表达式,这是你常用的东西。然后制作该正则表达式的硬编码版本。使用实际数量的数据进行比较,其中操作需要足够长的时间才能使加速变得重要。

我认为任何好的正则表达式引擎的内循环已经使用最先进的文本匹配算法进行了优化,并且经过优化可以快速完成。所以,如果表达式不是一件简单的事情(例如char类),那么用自己的代码加快速度就好了。

显然存在开销,您可以硬编码以自己的方式进行操作并实现良好的线性加速,其他条件相同。但这是拥有良好算法的次要因素,如果您不熟悉算法复杂性的概念,请先read up on that


但是有一个关键的东西,几乎是实际使用的一个显示器。 Regexp引擎必须正确。它必须找到它的假设,没有误报。如果您得到错误匹配或错过匹配(例如数据损坏),则可能会发生错误。你如何对发动机有足够的信心,敢于使用它?

创造一个好玩的,当然。对于真正的生产用途......嗯......


如果您有可能认真,那么您需要从一开始就进行自动化测试。对于像regexp这样的东西,您还需要为您的测试进行代码覆盖率分析。由于您将具有确定性输入和输出,无用户输入或任何内容,因此最终您应该针对代码的相关部分100%覆盖,无论是引擎还是生成的测试regexp代码。哦,当目标是速度时,不要忘记自动基准测试!当然你想要编码而不关心这些东西,这很好,但是从开始就设置基础设施,当你测试你的代码时,把它写成自动测试,拒绝手动进行临时测试的冲动(作为编写自动化测试用例的步骤除外)。如果你做得对,你的项目有更大的成功机会。

对于生成的代码,LLVM可能是你想要使用的,而不是某个特定CPU的汇编程序。

答案 3 :(得分:2)

你可能会从编译到机器指令的正则表达式中挤出更多的性能。这样做是否有意义完全取决于您如何分摊成本。

如果您正在尝试达到解析日志文件并具有截止日期的特定目标,那么在您验证现有库(包括{{}之前,考虑这一点可能没有意义。 3}})对你来说太慢了。在确定它是瓶颈之前担心你的RE性能是过早优化的经典案例。

但是,如果你想做这个挑战和学习练习,并且没有最后期限迫在眉睫,那么无论如何都要试一试。为很多工作做好准备,不要忘记写很多测试用例,因为会有bug。您的正则表达式引擎将成为整体工作产品的关键基础,您无法承受它在生产中行为不端。

祝你好运!