我有一个应用程序需要通过http批次(> 10k)下载大型xml文件(8-10MB),使用一个xpath表达式获取其中的一些内容。
我想知道如何优化这个过程。这些xml文件将直接进入Large Object Heap。 我在考虑三种选择: - 整体优化:使用单独的IO线程池下载xml文件 - 使用流来读取使用xml文件的Web响应,而不是读入将转到LOH的字符串(不确定是否可能以及如何这样做) - 使用Regex从XML检索内容,因为XPath非常简单,我不需要完整的DOM支持。
还有其他选择吗?
答案 0 :(得分:2)
有很多优化选项,具体取决于您想要最大化的内容。
如果您的处理速度比下载快(并且很难想象您的基于XPath的搜索会很慢),那么您的限制因素将是下载速度。您可以使用异步请求一次下载多个文件,但如果所有文件都来自同一台服务器,则不可能只有少数并发下载可以提高性能。
您可以在下载时从流中创建XmlReader
,并且(我认为,虽然我不确定)会针对流运行XPath表达式。但这并没有给你带来任何好处。
我认为你不必担心大对象堆。如果您一次下载并处理一个文件,则每个字符串将进入LOH,进行处理,然后进行收集。是的,存在对大型对象堆进行分段的潜在,但如果这些文件都在8到10 MB范围内,那么实际上你很可能遇到问题。必须有文件的病态安排。
你真的不必下载到字符串。您可以预先分配20 MB的缓冲区,然后下载到该缓冲区。然后将MemoryStream
包裹起来,在该内存流上创建一个XmlReader
等等。所以你的LOH根本不会被分割,因为你只是重新使用那个20 MB的缓冲区。除非我绝对不得不这样做,否则我真的不会走这条路。
如果我分配了这项任务,我会尽可能以最简单的方式完成。限制因素将是下载速度,因此我将集中精力进行任何优化工作。我根本不担心潜在的LOH碎片,但是将备用解决方案放在我的后袋中以防万一出现问题。
如何处理这个问题实际上取决于XPath搜索的速度。如果搜索10 MB的XML文件需要几毫秒甚至几秒钟,那么担心优化搜索就没有任何意义:下载时间会缩短搜索时间。相反,我会看到我是否可以获得两个或四个并发下载,当它进入时将每个字符串结果抛出到BlockingCollection
,并让消费者线程读取该队列并运行搜索。该消费者线程可能会花费大量时间闲置,等待下一个文件关闭。
简而言之:让它发挥作用,然后让它快速运作。