有没有支持即时编译的正则表达式引擎?

8 投票
9 回答
3886 浏览
提问于 2025-04-15 16:12

我的问题是

有没有那种在解析正则表达式模式时能进行即时编译的正则引擎?而且在匹配或替换文本时也能用到?或者我可以在哪里学习i386或x64架构的即时编译?

我为什么需要它

最近我在对比Python内置的正则引擎和普通C代码的性能,数据大约有10MB。

我发现对于简单的替换(比如把 ab 替换成 zzz),速度还算快:大约比C慢2到3倍。

但是对于 [a-z]c,它的速度大约是C的5到8倍慢。

而使用分组(例如 ([a-z])(c) 替换成 AA\2\1BB)时,速度是C的20到40倍慢。

虽然现在还没有实现即时编译,但我觉得如果能做到即时编译,速度会快很多。

顺便说一下:我在编译模式时会对每个正则模式进行性能分析,比如,简单的 ab 用分析1,范围 [a-z]c 用分析2,带分组的 ([a-z])(c) 用分析3,每个分析都有独立的代码,这样在匹配和替换简单模式时就不会有额外的开销。

更新 1

我试过用psyco,但速度提升不大。可能是因为我是在处理大数据的文本替换,而不是循环很多次。

如果我没记错的话,Python的 re.sub 已经是原生运行的,所以psyco可能无法大幅提升速度。

更新 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;

有没有什么想法?

9 个回答

2

我在你的问题里没看到这个,所以我想问一下:你有没有试过用预编译的正则表达式,比如“re.compile(pattern)”?

因为预编译的正则表达式通常会更快。虽然这不是即时编译(JIT),但大多数情况下,使用预编译的正则表达式就足够了!

你可以看看这里:

re.compile

5

从8.20版本开始,PCRE(Perl兼容正则表达式)有了一个即时编译器(JIT)。你可以在这里了解更多信息:http://sljit.sourceforge.net/pcre.html

3

我知道的唯一一个可以把正则表达式编译成可执行代码的正则引擎是.NET中的那个,当你传入RegexOptions.Compiled时。这样做会让Regex类生成MSIL代码,这种代码可以像其他.NET代码一样被即时编译。

不过,这并不意味着.NET的正则引擎一定比其他的快。在处理大型数据集时,如果使用相对简单的正则表达式进行搜索和替换,字符串的处理变得更加重要。因为.NET中的字符串是不可变的,所以字符串需要重新分配的次数会影响性能。

手动编写操作总是会更快,因为手写的代码和正则表达式的代码并不完全相同。正则表达式的代码会保留一些关于匹配和捕获组的信息,而你的代码可能没有。在大多数情况下,手动编写搜索和替换的额外时间并不值得,特别是当你考虑到如果需求变化,切换到不同的正则表达式是很简单的,而用过程代码重写搜索和替换则需要花费更多时间。

根据我的经验,PCRE是最快的正则引擎之一。不过,它并没有提供现成的搜索和替换功能。

撰写回答