Java中的并行XML解析

Java中的并行XML解析,java,xml,multithreading,parallel-processing,xml-parsing,Java,Xml,Multithreading,Parallel Processing,Xml Parsing,我正在编写一个应用程序,它处理大量具有深层节点结构的xml文件(>1000)。使用(事件API)解析一个包含22.000个节点的文件大约需要6秒钟 该算法被放置在一个用户交互过程中,只有几秒钟的响应时间是可以接受的。因此,我需要改进如何处理xml文件的策略 我的流程分析xml文件(只提取几个节点) 处理提取的节点,并将新结果写入新的数据流(生成具有修改节点的文档副本) 现在我正在考虑一个多线程解决方案(在16核+硬件上扩展得更好)。我想到了以下策略: 创建多个解析器并在xml源上并行运行它们 重

我正在编写一个应用程序,它处理大量具有深层节点结构的xml文件(>1000)。使用(事件API)解析一个包含22.000个节点的文件大约需要6秒钟

该算法被放置在一个用户交互过程中,只有几秒钟的响应时间是可以接受的。因此,我需要改进如何处理xml文件的策略

  • 我的流程分析xml文件(只提取几个节点)
  • 处理提取的节点,并将新结果写入新的数据流(生成具有修改节点的文档副本) 现在我正在考虑一个多线程解决方案(在16核+硬件上扩展得更好)。我想到了以下策略:

  • 创建多个解析器并在xml源上并行运行它们
  • 重写我的解析算法线程保存以仅使用解析器的一个实例(工厂,…)
  • 将XML源拆分为块,并将块分配给多个处理线程()
  • 优化我的算法(比woodstox更好的StAX解析器?/使用内置并发解析器
  • 我想提高整体性能和“每个文件”性能。


    你有处理这些问题的经验吗?最好的办法是什么?

    我同意吉姆的看法。我认为,如果您想提高1000个文件的总体处理性能,那么您的计划是好的,除了#3在这种情况下是不相关的。 然而,如果您想提高单个文件的解析性能,您就有一个问题。我不知道如何在不解析XML文件的情况下拆分XML文件。每个块都是非法的XML,您的解析器将失败

    我相信提高整体时间对你来说已经足够好了。在这种情况下,请阅读本教程: 然后创建线程池,例如100个线程和包含XML源的队列。每个线程只解析10个文件,这将在多CPU环境中带来巨大的性能优势

  • 这一点很明显:只需创建几个解析器并在多个线程中并行运行它们

  • 看一看(目前,请尝试谷歌缓存)

  • 若XML的结构是可预测的:若它有许多相同的顶级元素,那个么这是可以做到的。例如:

    <element>
        <more>more elements</more>
    </element> 
    <element>
        <other>other elements</other>
    </element>
    
    
    更多元素
    其他要素
    
    在这种情况下,您可以创建一个简单的拆分器来搜索
    ,并将此部分提供给特定的解析器实例。这是一种简化的方法:在现实生活中,我会使用RandomAccessFile查找开始点和停止点(
    ),然后创建只对文件的一部分进行操作的自定义FileInputStream

  • 看一看。就是创造Woodstox的那些人。这是这一领域的专家,不要重新发明轮子


  • 除了现有的好建议之外,还有一件相当简单的事情要做:使用游标API(XMLStreamReader),而不是事件API。事件API增加了30-50%的开销,而没有(仅IMO)显著简化处理。事实上,如果你想方便的话,我建议你改用;它构建在游标API之上,不会增加大量开销(与手工编写的代码相比最多为5-10%)

    现在:我假设您已经对Woodstox进行了基本的优化;但如果不是,请查看“”。具体而言,你绝对应该:

  • 确保只创建一次XMLInputFactory和XMLOutputFactory实例
  • 关闭读写器,以确保缓冲区回收(和其他有用的重用)按预期工作
  • 我提到这一点的原因是,虽然这些没有功能上的差异(代码按预期工作),但它们可以带来很大的性能差异;尽管在处理较小的文件时更是如此


    运行多个实例也有意义;虽然通常每个核心最多有一个线程。但是,只要您的存储I/O能够支持这样的速度,您就只能从中受益;如果磁盘是瓶颈,这将无济于事,而且在某些情况下会造成伤害(如果磁盘是竞争对手)。但值得一试。

    现在还不清楚什么需要最大化。。。单个文件的性能,或所有1000个文件的总性能。还有一个建议:如果您可以量化文件大小,允许计算吞吐量(每秒处理的兆字节数),则可以给出预期性能的概念。在测试时,我使用Woodstox进行解析通常会得到10-40MB/s的速度;但是我的硬盘只能提供5-10 MB/s的持续速度。+1:虽然如果解析足够简单,主要问题是IO,那么性能可能不会有多大提高。