寻找使用python优化文本解析速度的实用解决方案

时间:2011-05-28 10:02:01

标签: python parsing optimization text-parsing

需要使用一组不同的命名正则表来解析一组行。

每行都会通过每个正则表达式,直到找到匹配项。 当找到匹配时,代码应返回/ yield(命名为regex,value)对每行。

文件大小为2GB +所以我正在寻找一些提高解析器速度的想法。

目前代码是通过python执行的,但该部分是可以更改的。 一种选择是将所有内容转换为C以从PCRE获得更快的速度和更快的(?)IO,但这是一条很难在将来维护的慢速路径。

我正在寻找实用的解决方案,如:

  • 将解析器转换为更快的语言
  • 转向cython(?)
  • 以多个块分割文件并在少数线程之上运行

3 个答案:

答案 0 :(得分:4)

首先,我不担心转换到另一种语言。替代战略可能会产生更大的利益。 python使用的regexp引擎无论如何都是用C编写的(iirc)。

  1. '优化'正则表达式,如果可能是你的第一个任务。如何执行此操作取决于您的文本和表达式。有文章和示例look。 @ThomasH也提出了一个很好的观点。
  2. 优化正则表达式的最简单方法是删除它;查看是否有机会切换到其他测试,例如x in yline.endswith()等。
  3. 尝试使用pypy运行代码。它可以在不修改代码的情况下提高性能。在你的情况下,虽然收益可能是微不足道的,因为性能与你的正则表达式和文件io绑定。
  4. 跨多个线程/进程并发处理文件可能是有益的。我建议使用一个进程来读取文件并将行推送到多个进程从中拉出的队列。有很多方法可以做到这一点。看看http://effbot.org/zone/wide-finder.htm#a-multi-processor-python-solution

答案 1 :(得分:3)

加速Python模式匹配的一个重点是尝试使用单个正则表达式。因此,不是通过每行输入的正则表达式列表,而是将正则表达式与|组合成一个,然后对每一行应用此正则表达式一次:

reg = re.compile(r'''
    (?<patt1>foo)
    |(?<patt2>bar)
''', re.VERBOSE)

for line in lines:
    mo = reg.search(line)
    if mo:
        yield (mo.lastgroup(), mo.group(mo.lastgroup()))

答案 2 :(得分:1)

我想到的第一件事是你应该使用 re.compile()来准备所有正则表达式。但我想这已经完成了!

要考虑的另一件事可能是分层处理:

根据您所拥有的正则表达式的类型,可以将它们组织为分层。通过这种方式,您可以预先过滤线条,只将它们输入您需要检查的正则表达式。

例如,如果您搜索“&lt; body attr1 attr2&gt;”等标记在正则表达式中,在检查它是否真的是一个标记之前,可能有助于在该行中搜索该行的“body”。你也可以搜索“&lt;”在使用与标签相关的正则表达式之前。

如果将多个表达式合并为一个并检查匹配,它也可以加快处理速度。就像用{{term1 | term2)}“替换”{term1}“”{term2}“的单个支票一样。

然后您可以尝试通过定义它们所处理的最小行长度来过滤需要检查的正则表达式。

这样简单的东西可以加速你的应用程序,而无需切换到另一种语言或cpu。

如果可能,您也可以尝试多线程。根据CPU的可用性,您可以在两个线程中处理每隔一行,这也可以大大加快处理速度。