如何使用大型xml文件优化操作(下载/解析)

本文关键字:下载 解析 优化操作 何使用 大型 xml 文件 | 更新日期: 2023-09-27 18:25:08

我有一个应用程序,需要通过http下载大量(>10k)的大型xml文件(8-10MB),使用一个xpath表达式获取其中的一些内容。

我想知道如何优化这个过程。这些xml文件将直接进入大型对象堆。我正在考虑三种选择:-整体优化:使用单独的IO线程池下载xml文件-使用流读取带有xml文件的web响应,而不是读取将进入LOH的字符串(不确定是否可能以及如何做到这一点)-使用Regex从XML中检索内容,因为XPath非常简单,我不需要完全的DOM支持

还有其他选择吗?

如何使用大型xml文件优化操作(下载/解析)

根据您想要最大化的内容,有很多优化选项。

如果您的处理速度比下载速度快(而且很难想象基于XPath的搜索会很慢),那么您的限制因素将是下载速度。您可以使用异步请求一次下载多个文件,但如果所有文件都来自同一台服务器,则不太可能通过多次并发下载来提高性能。

您可以在下载时从流中创建一个XmlReader,然后(我认为,尽管我不确定)针对流运行XPath表达式。但这并没有给你带来任何好处。

我认为您不必担心大型对象堆。如果您一次下载和处理一个文件,那么每个字符串都将进入LOH,进行处理,然后被收集。是的,有分割大型对象堆的潜力,但如果文件都在8到10MB的范围内,那么在实践中就不太可能出现问题。必须对文件进行病态的整理。

而且你真的不需要下载到一个字符串。您可以预先分配一个缓冲区,比如20 MB,然后下载到该缓冲区。然后将一个MemoryStream封装起来,在该内存流上创建一个XmlReader,等等。这样你的LOH就不会因为重复使用20 MB的缓冲区而变得支离破碎。除非万不得已,否则我真的不会走这条路。

如果我被分配了这项任务,我会用最简单的方式完成。限制因素将是下载速度,所以这是我集中精力进行优化的地方。我一点也不担心潜在的LOH碎片化,但把替代解决方案放在我的口袋里,以防出现问题。

如何实现这一点实际上取决于XPath搜索的速度。如果搜索一个10MB的XML文件需要几毫秒甚至几秒钟的时间,那么担心优化搜索是没有意义的:下载时间将使搜索时间相形见绌。相反,我会看看是否可以获得两到四次并发下载,当每个字符串结果出现时,将其放入BlockingCollection中,并让一个消费者线程读取该队列并运行搜索。该使用者线程可能会花费大量空闲时间,等待下一个文件下来。

简而言之:让它工作,然后让它快速工作。