使用多处理解析非常大的XML文件

时间:2014-01-27 12:26:50

标签: python xml multiprocessing

我有一个巨大的XML文件,我对如何处理它有点不知所措。它是60 GB,我需要阅读它。

我在想是否有办法使用多处理模块来读取python文件?

有没有人有这样的样本,他们可以指出我?

谢谢

2 个答案:

答案 0 :(得分:4)

对于那个大小的文件,我建议你使用流式XML解析器。在Python中,这将是来自cElementTree或lxml.etree的iterparse方法:

http://effbot.org/zone/element-iterparse.htm

答案 1 :(得分:2)

保存解析非常大的XML文件的内存 您可以使用这个比effbot.org更新的代码,它可以为您节省更多内存: Using Python Iterparse For Large XML Files

多处理/多线程 如果我没记错的话,在加载/解析XML时,不能轻易地进行多处理以加快处理速度。如果这是一个简单的选择,那么每个人都可能已经默认这样做了。 Python通常使用全局解释器锁(GIL),这会导致Python在一个进程内运行,并且这绑定到CPU的一个核心。当使用线程时,它们在主Python进程的上下文中运行,该进程仍然只绑定到一个核心。在Python中使用线程可能会因上下文切换而导致性能下降。在多个内核上运行多个Python进程带来了预期的额外性能,但那些不共享内存,因此您需要进程间通信(IPC)以使进程协同工作(您可以在池中使用多处理,它们在工作完成时同步但主要用于(不是)有限的小任务。我需要共享内存,因为每个任务都在使用同一个大XML。 然而,LXML可以通过某种方式解决GIL问题,但它只能在某些条件下提高性能。

在LXML中进行线程化 为了在lxml中引入线程,常见问题解答中有一部分讨论了这个问题:http://lxml.de/FAQ.html#id1

我可以使用线程同时访问lxml API吗?

简短回答:是的,如果您使用lxml 2.2及更高版本。

从1.1版开始,只要您使用默认解析器(为每个线程复制)或自己为每个线程创建解析器,lxml在从磁盘和内存进行解析时会在内部释放GIL(Python的全局解释器锁) 。 lxml还允许在验证(RelaxNG和XMLSchema)和XSL转换期间进行并发。您可以在线程之间共享RelaxNG,XMLSchema和XSLT对象

如果我使用线程,我的程序运行得更快吗?

取决于。回答这个问题的最好方法是计时和分析。

Python中的全局解释器锁(GIL)序列化对解释器的访问,因此如果您的大部分处理都是在Python代码中完成的(步行树,修改元素等),您的增益将接近于零。然而,越多的XML处理进入lxml,你的收益就越高。如果您的应用程序受XML解析和序列化的约束,或者非常有选择性的XPath表达式和复杂的XSLT,那么您在多处理器计算机上的加速可能会很大。

请参阅上面的问题,了解哪些操作可以释放GIL以支持多线程。

有关优化解析大型XML的性能的其他提示 https://www.ibm.com/developerworks/library/x-hiperfparse/