Python:并行编译正则表达式

Cha*_*ert 6 python regex parallel-processing multiprocessing

我有一个程序,我需要编译几千个大型正则表达式,所有这些都将被使用多次.问题是,它们需要太长时间(根据cProfiler,113秒)re.compile().(顺便说一句,实际上使用所有这些正则表达式进行搜索,一旦编译就会<1.3秒.)

如果我不预编译,它只是将问题推迟到我实际搜索时,因为re.search(expr, text)隐式编译expr.实际上,它更糟糕,因为re每次我使用它们都会重新编译整个正则表达式列表.

我尝试过使用multiprocessing,但这实际上减慢了速度.这是一个小测试来证明:

## rgxparallel.py ##
import re
import multiprocessing as mp

def serial_compile(strings):
    return [re.compile(s) for s in strings]

def parallel_compile(strings):
    print("Using {} processors.".format(mp.cpu_count()))
    pool = mp.Pool()
    result = pool.map(re.compile, strings)
    pool.close()
    return result

l = map(str, xrange(100000))
Run Code Online (Sandbox Code Playgroud)

我的测试脚本:

#!/bin/sh
python -m timeit -n 1 -s "import rgxparallel as r" "r.serial_compile(r.l)"
python -m timeit -n 1 -s "import rgxparallel as r" "r.parallel_compile(r.l)"
# Output:
#   1 loops, best of 3: 6.49 sec per loop
#   Using 4 processors.
#   Using 4 processors.
#   Using 4 processors.
#   1 loops, best of 3: 9.81 sec per loop
Run Code Online (Sandbox Code Playgroud)

我猜这个并行版本是:

  1. 同时,编译和酸洗正则表达式,约2秒
  2. 串行,非酸洗,因此重新编译它们,约6.5秒

加上启动和停止进程的开销,multiprocessing4个处理器比串行 25%以上.

我还尝试将正则表达式列表分为4个子列表,以及 - pool.map子列表,而不是单个表达式.这给了一个小的性能提升,但我仍然不能比串行慢〜25%.

有没有比串行编译更快的方法?

编辑: 更正了正则表达式编译的运行时间.

我也试过使用threading,但由于GIL,只使用了一个处理器.它略好于multiprocessing(130秒对136秒),但仍然比连续(113秒)慢.

编辑2: 我意识到一些正则表达式可能是重复的,所以我添加了一个用于缓存它们的字典.剃光了约30秒.不过,我仍然对并行化很感兴趣.目标机器有8个处理器,可将编译时间缩短到约15秒.

Bri*_*ius -2

尽管我很喜欢Python,但我认为解决方案是用perl (例如,参见这个速度比较)或C等来完成。

如果你想将主程序保留在 python 中,你可以使用subprocess调用 perl 脚本(只需确保在尽可能少的调用中传递尽可能多的值,subprocess以避免开销。