在python中编写一个快速解析器

时间:2010-04-27 16:24:46

标签: python parsing arff

我已经为一个讲座中的一些文件格式(ARFF)编写了一个动手的递归纯python解析器。现在运行我的运动提交非常缓慢。到目前为止,解析器花费的时间最多。它消耗了大量的CPU时间,HD不是瓶颈。

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

我当前的解析器只需要预览一个字符。我会在这里发布消息来源,但我不知道这是不是一个好主意。在所有提交截止日期尚未结束之后。但是,本练习的重点不是解析器。您可以选择要使用的任何语言,并且已经有Java解析器。

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

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

2 个答案:

答案 0 :(得分:8)

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

如果您想保留当前的代码,可能需要查看Cython / PyPy,这会提高您的性能(有时高达4倍)。

答案 1 :(得分:7)

我没有提供进一步信息的最常见提示是将整个文件或至少其中的大部分文件一次性读入内存。你不想一次读一个角色并在这里和那里寻求;无论在引擎盖下发生什么缓冲,只要将整个内容放在内存中就可以了,这样你就可以根据自己的需要进行操作。

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

在Python中,人们陷入的一个陷阱就是做了很多不必要的字符串操作。不要一次追加一个字符串;当你构建你的令牌时,你要对“主”字符串进行工作,并一举剥离令牌。 (换句话说,索引到“主”字符串,找出起点和终点,然后用token = master[start:end]抓住它。)执行字符串连接一次一个字符是性能不佳的短路径。我怀疑,即使你想要/需要某些理由for c in master: newstr += c,你可能会更好地将'c'填入列表然后newstr = ''.join(newstr_charlist)