使用cffi和re2实现部分Python内置re模块功能(兼容pypy)

从一些benchmark可以看出,Python内置的re模块比起re2是慢很多的。而Google的re2(https://code.google.com/p/re2/)是一个速度快的C++正则库。是否可以在Python内利用re2呢?有一些人已经做了相关的工作:facebook/pyre2 axiak/pyre2,但这些都是采用CPython扩展/Cython的方式编写,在pypy下不能正常使用。如何既能得到pypy的速度,也能利用re2?首先想到了CPython和pypy都内置的ctypes模块,可以用来访问C编写的so库。

但从实际测试结果来看,在pypy下使用ctypes是比较慢的,有人也报了BUG(https://bugs.pypy.org/issue1237),但仍未解决。测试数据如下:

还有另外一个第三方库:cffi(http://cffi.readthedocs.org/),可以实现类似ctypes的访问C库并调用其函数的功能。跟ctypes一样,cffi也只能访问C的so,无法直接访问C++的so,因此我们要为re2包装一层,暴露C接口。具体代码在github。从上面的测试可以看出,cffi_re2在某些正则下是原生re模块的速度的50倍,但有些正则却会比原生的慢……

使用了我们生产的真实数据和真实正则测试,测试代码:https://gist.github.com/vls/7539716(涉及公司数据,这里无法给出测试数据),在CPython和pypy下都能取得一些性能上的提升:)