【问题标题】:Is there any regular expression engine that does Just-In-Time compiling? [closed]是否有任何进行即时编译的正则表达式引擎? [关闭]
【发布时间】:2010-12-18 15:33:45
【问题描述】:

我的问题是

是否有任何正则表达式引擎在正则表达式模式解析期间进行即时编译并在匹配/替换文本时使用?或者我在哪里可以学习 i386 或 x64 架构的 JIT?

为什么我需要它

我最近trying to benchmark Python’s built-in regex engine 与大约 10MB 数据的普通 C 代码相比。

我发现对于直接替换(例如 abzzz),它相对较快:仅比 C 慢 2 到 3 倍。

但是对于[a-z]c,它花费的时间大约是 C 的 5 到 8 倍。

并且使用分组(例如 ([a-z])(c)AA\2\1BB )花费的时间是 C 的 20 到 40 倍。

它还不是即时编译,但我认为,如果我可以进行即时编译,它的速度会更快。

PS:我在编译模式期间对每个正则表达式模式使用分析, 例如,配置文件 1 用于简单的 ab,配置文件 2 用于范围 [a-z]c,配置文件 3 具有分组 ([a-z])(c),每个配置文件都有单独的代码,因此在匹配和替换简单模式时不需要额外的成本。

更新 1

我已经用 psyco 试过了,它并没有提高速度。 可能是因为我正在对大数据进行文本替换,而不是循环多次。

如果我没记错的话,我认为 Python 的 re.sub 已经在原生运行它,所以 pysco 无法提高速度。

更新 2

我尝试过将 boost 正则表达式封装到 python 中,但它甚至比 Python 的正则表达式还要慢,所以瓶颈似乎在于 Python 的字符串处理,Jan Goyvaerts 在答案中也指出了这一点。

更新

我想将正则表达式模式ab[a-z]c 转换为机器代码,如以下等效的 C 代码(*s 指向 10MB 长文本):

do{
    if(*s=='a' && s[1]=='b' && s[2]>='a' && s[2]<='z' && s[3]=='c') return 1;
}while(*s++);
return 0;

有什么想法吗?

【问题讨论】:

  • 只是一个想法。如果你使用 Boost.Regex 你会得到什么结果?
  • 好的,我很快就会用 Boost 进行测试。谢谢
  • eh... 我相信那篇文章是说正则表达式的流行实现具有算法效率低下。编译它们可能会以恒定的因素改善事情,但它不会解决根本问题。
  • @Mark:不要评论你自己的问题。请使用 cmets 中的所有其他答案更新您的问题。你拥有这个问题。你可以澄清一下。请澄清问题并使 cmets 无关紧要。
  • 我通过近距离投票审核队列得到了这个问题。这已被标记为 off-topic,原因是库和软件建议在此站点上与主题无关。但是,对该原因的描述也建议“描述问题以及迄今为止为解决该问题所做的工作”。这已经完成了。这个问题并不完全归结为软件推荐请求。保持打开状态。

标签: c++ python c regex jit


【解决方案1】:

PCRE 从 8.20 开始就有 JIT 编译器。你可以在这里阅读:http://sljit.sourceforge.net/pcre.html

【讨论】:

    【解决方案2】:

    我所知道的唯一可以将正则表达式编译成可执行代码的正则表达式引擎是 .NET 中传递 RegexOptions.Compiled 时的引擎。这会导致 Regex 类发出 MSIL,然后可以像任何其他 .NET 代码一样 JITted。

    是否使 .NET 正则表达式引擎比其他引擎更快是完全不同的问题。在大型数据集上使用相对简单的正则表达式进行搜索和替换时,字符串处理变得更加重要。 .NET 字符串是不可变的,很大程度上取决于字符串需要重新分配多少次。

    手动编码操作总是会更快,因为代码是不等价的。正则表达式代码维护有关正则表达式匹配和您的代码没有的捕获组的某些信息。在大多数情况下,您花在手动编码搜索和替换而不是使用正则表达式上的额外时间是不值得的,特别是如果您考虑到当您的需求发生变化时切换到不同的正则表达式是微不足道的,同时重写使用过程代码的搜索和替换需要更多时间。

    根据我的经验,PCRE 是最快的正则表达式引擎之一。但是,它不包括现成的搜索和替换。

    【讨论】:

    • 感谢您提供有关 .NET 正则表达式和出色解释的信息。
    【解决方案3】:

    我不是 Python 专家,但你可以试试 Psycho:

    http://www.ibm.com/developerworks/library/l-psyco.html

    http://psyco.sourceforge.net/

    【讨论】:

    • 谢谢,我会再试一次。
    • 不客气,马克。请注意,这可能比简单地在脚本顶部添加 psyco.jit() 有点棘手:请务必阅读 IBM 教程。祝你好运!
    • @Bart - 我明白了,我刚刚尝试使用 psyco.full(), ([a-z])(c) 模式在我当前的 780 万字符的电脑上变慢了 25 倍,之前慢了 30 倍。我现在正在阅读 IBM 教程。谢谢。再次。
    【解决方案4】:

    Firefox 中的正则表达式引擎将一些(不是全部!)正则表达式编译为机器码。我相信 Safari 和 Chrome 也是如此。

    【讨论】:

      【解决方案5】:

      我没有在您的问题中看到它,所以我问:您是否使用预编译的正则表达式进行测试,例如“重新编译(模式)”??

      因为编译的正则表达式应该更快。好吧,它不是 JIT,但大多数时候你只需要简单的预编译就可以了!

      看这里:

      re.compile

      【讨论】:

      • 哦,好吧,我没有意识到做 re.compile 更快,让我测试一下。
      • 似乎 re.compile 对我没有任何帮助,顺便说一句,我正在使用 re.sub("([az])(c)","AA\\2 \\1BB",不像我在百万循环中重新编译。无论如何,谢谢
      • 哦,我现在更清楚地看到了你的问题。
      • 但是你应该在循环之前执行re.compile,然后在循环中运行编译好的正则表达式。
      • re 模块编译并缓存字符串正则表达式,因此预编译正则表达式通常不会改变匹配的速度。
      【解决方案6】:

      另一个想法:当你有一个比 Python 正则表达式模块更优化的库(在 C 中)或者对正则表达式进行即时编译时,你可以为 python 编写自己的正则表达式模块,它只是包装你的 C 库。

      这当然需要更多的工作,并且仅在您真的非常需要速度时才推荐。

      你也可以试试Cython(我个人还没用过,但听起来还不错)来做包装的工作。

      就我现在了解您的问题而言,Python 周围不是您的问题(所以我怀疑 psyco 是否会有所帮助)- regex-run 的准备也不是您的问题,但运行本身必须是 top -速度。这当然取决于您使用的库以及它处理大字符串的能力。我认为,标准的 python regex-lib 没有针对如此长的字符串和一流的速度进行优化。

      【讨论】:

      • 感谢您的提示,实际上,我已经将我的 C 代码打包到 python 并测试了 python 正则表达式和我的硬编码 C 代码作为 python 扩展。
      【解决方案7】:

      所以,如果我理解正确的话,您使用的编程语言默认不进行即时编译,而现在您正在寻找能够准确执行此操作的正则表达式库?

      我认为您应该使用例如将所有 python 代码编译为二进制文件。精神科

      http://www.devshed.com/c/a/Python/How-Python-Runs-Programs/4/

      这里也讨论过:

      Is it feasible to compile Python to machine code?

      这里:

      Is it possible to compile Python natively (beyond pyc byte code)?

      如果这些解决方案不起作用或仍然不够快,并且如果您绝对想用 python 编写应用程序的其余部分,则可以使用 boost python c++ 库:

      http://www.boost.org/doc/libs/1_41_0/libs/python/doc/index.html

      boost.python 库允许 python 和 c++ 之间的完全互操作性。然后,您可以使用 boost.regex c++ 正则表达式匹配器:

      http://www.boost.org/doc/libs/1_41_0/libs/regex/doc/html/index.html

      【讨论】:

      • 谢谢,我会尝试再次启用 psyco 进行测试。
      • >> 您正在寻找一个正则表达式库,可以做到这一点。是的,有点,我刚刚用 psyco 进行了测试,它实际上并没有太大的改进,我的想法是,将 [a-z]c 转换为类似 C 中硬编码的机器代码。thx
      • 我添加了对 boost.python 和 boost.regex 的引用。
      【解决方案8】:

      我可能错了,但我相信 Python 的正则表达式模块是用 C 语言编写的,所以任何编译 Python 的建议(比如使用 Psycho)都不会有太大的不同——你实际上比较的是一个 C 语言的性能正则表达式库(Python)与另一个(无论您使用什么库)。

      【讨论】:

      • 是的,我也是这样想的。如果我没记错的话,实际代码在 sre.c 中。
      【解决方案9】:

      Thompson 于 1968 年在 ACM 的通讯中发表了一篇论文,其中描述了将正则表达式转换为 IBM 7094 代码的有效 JIT 编译器。我不知道他使用什么语言; Fortran 或 LISP 是明显的嫌疑人,尤其是 LISP,因为它已经进行了 JIT 编译。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多