11

我已经为我们在一次讲座中使用的某种文件格式( ARFF )编写了一个动手递归纯 python 解析器。现在运行我的练习提交非常慢。到目前为止,大部分时间都花在了我的解析器上。它消耗大量CPU时间,HD不是瓶颈。

我想知道在 python 中编写解析器有哪些高效的方法?我宁愿不要用 C 重写它。我尝试使用 jython,但这大大降低了性能!我解析的文件部分很大(> 150 MB),行很长。

我当前的解析器只需要一个字符的前瞻。我会在这里发布源代码,但我不知道这是否是个好主意。毕竟提交截止日期还没有结束。但是,本练习的重点不是解析器。您可以选择您想使用的任何语言,并且已经有一个 Java 解析器。

注意:我有一个 x86_64 系统,所以 psyco(它似乎也是 PyPy)不是选项。

更新:我现在将我的解析器/写入器上传到bitbucket

4

2 回答 2

10

您可以使用ANTLRpyparsing,它们可能会加快您的解析过程。

如果你想保留你当前的代码,你可能想看看Cython / PyPy,它可以提高你的性能(有时高达 4 倍)。

于 2010-04-27T16:30:29.487 回答
9

在没有更多信息的情况下,我给出的最一般的提示是一次将整个文件或至少其中的大部分内容读入内存。您不想一次读一个字符并到处寻找;不管引擎盖下的缓冲是什么,把整个东西放在内存中可能是个好主意,这样你就可以随心所欲地操作它。

我已经用 Python 编写了解析器,并且没有特别要求它们比用任何其他语言编写的解析器特别慢。与这类事情一样,您更有可能在做您不需要做的工作。在这些物品类别中,创建、销毁和重新创建同一个对象比将其存储在某个地方更昂贵。一遍又一遍地重新计算一个值比将它存储在某个地方更昂贵。等等等等。

特别是在 Python 中,人们陷入的一个陷阱是进行大量不必要的字符串操作。不要一次附加一个字符的字符串;当你建立你的令牌时,在“主”字符串上做你的工作,并一举去除令牌。(换句话说,索引到“主”字符串,找出起点和终点,然后用token = master[start:end].)一次一个字符进行字符串连接是导致性能下降的捷径。我怀疑即使您出于某种原因想要/需要这样做,for c in master: newstr += c您可能会更幸运地将 'c' 填充到列表中,然后newstr = ''.join(newstr_charlist).

于 2010-04-27T17:03:44.067 回答