8

我的问题是

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

为什么我需要它

我最近尝试将 Python 的内置正则表达式引擎与具有大约 10MB 数据的普通 C 代码进行比较。

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

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

通过分组(例如([a-z])(c)to AA\2\1BB),它花费的时间是 C 的 20 到 40 倍。

它还不是即时编译,但我认为,如果我可以进行即时编译,它可以加快很多。

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

更新 1

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

如果我没记错的话,re.sub我认为 Python 已经在本地运行它,所以 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;

有任何想法吗?

4

9 回答 9

5

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

于 2011-12-30T22:55:51.343 回答
3

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

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

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

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

于 2009-11-23T14:30:52.253 回答
2

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

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

http://psyco.sourceforge.net/

于 2009-11-20T08:47:07.853 回答
2

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

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

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

这里也讨论过:

将Python编译成机器码可行吗?

和这里:

是否可以本地编译 Python(除了 pyc 字节码)?

如果这些解决方案不起作用或仍然不够快,并且如果您绝对想用 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

于 2009-11-20T08:47:17.073 回答
2

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

于 2009-11-20T08:52:12.973 回答
2

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

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

看这里:

重新编译

于 2009-11-20T08:52:40.743 回答
2

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

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

您也可以尝试使用Cython(我个人还没有使用它,但听起来相当不错)来完成包装工作。

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

于 2009-11-20T09:38:52.663 回答
1

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

于 2009-11-20T18:06:28.263 回答
1

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

于 2010-02-04T15:17:24.400 回答