gpt4 book ai didi

XML 解析性能 Scala

转载 作者:数据小太阳 更新时间:2023-10-29 02:23:46 25 4
gpt4 key购买 nike

我在 Scala 中使用 XML,在具有有限内存 资源的系统中解析可以达到 ~20MB 的文件。我必须读取整个文件,并且必须从中提取所有数据。更具体地说,我必须读取的节点具有有限的属性和值。

我想知道在性能方面最好的方法是什么(或者两者是否具有相同的性能)。我问这个是因为我不知道 Scala 如何处理它的 XML 库,而且我可能会遗漏一些细节。

第一种方法

def firstApproach(root: Elem) = 
for { n <- root \ "node" } yield handleNodeAttribute(n)

private def handleNodeAttribute(n: Node) = n match {
case node @ <node /> if (node \ "@attr").text == "type1" => // do something
// here other possible cases -> type2, type3
}

第二种方法

def secondApproach(root: Elem) = {
val nodes = root \ "node"
val type1 = filterNodesByAttribute(nodes, "attr", "type1")
// and so on -> type2, type3
}

private def filterNodesByAttribute(nodes: NodeSeq, attr: String, value: String) = {
nodes filter (node => (node \ ("@" + attr)) text == value)
}

那么,与使用模式匹配和每个问题迭代一次(for-yield 循环)相比,使用 XPath 方法处理所有文件有什么优势吗?

最佳答案

这两种解决方案的性能将是相似的,并且可能都不适合您的内存限制。

当我们谈论 XML 处理时,通常有两种类型的方法,DOM 处理和流式 处理。

DOM处理

DOM 处理读取整个源文档,然后允许程序员对内存表示 执行操作。从程序员的角度来看,这通常是处理 XML 文档的最简单方法,但是所使用的内存与 XML 文档的大小成正比。这意味着处理大型文档会占用大量内存。

流处理

流式处理 处理读取 XML 文档并在读取时动态处理文档。从程序员的角度来看,这使得文档更难使用,因为他不能同时访问整个文档,只能访问一小部分。它具有持续使用内存的优点。也就是说,您不需要在内存中保存整个文档,只需保存您正在操作的部分。

鉴于您的内存限制,您几乎肯定必须使用流式处理方法。使用流式方法,您可以读取文件,提取您感兴趣的部分,然后继续,从而不会为您不感兴趣的文档部分积累额外的内存。

请注意,如果您从文件中提取大量 信息并将其保存在内存中,您将有效地抵消流式处理的好处,因为您只是将所有数据保存在无论如何内存。如果您发现自己处于这种情况并且遇到内存问题,请考虑在读入数据后将数据流式传输到文件中,而不是将其保存在内存中。您可以将流式传输视为对 XML 的转换。您阅读整个文档一次,转换(保留/更改/丢弃)您感兴趣的部分,并在转换完成后立即将它们写出来。

scala.xml

现在,scala.xml 包使用 DOM 样式方法来处理 XML,因此它可能不适合您。您的两个解决方案都建立在这个包之上。我建议与具有 XML 流支持的 Java 库交互(我不知道有任何 Scala 库支持)。

javax.xml

Java 标准库已经有各种工具以流方式处理 XML。我个人只将这些工具用于基于流的 编写 XML 文件,但它们应该非常简单,并且非常适合任何场景。

jackson

Jackson( https://github.com/FasterXML/jackson-core ) 支持基于流的 XML 处理,这可能比 javax.xml 中的 API 功能更丰富。确保您使用他们的流式 API,因为他们也有基于 DOM 的 API,这将再次给您留下内存问题。

关于XML 解析性能 Scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28035092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com