Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala的XML解析性能_Xml_Performance_Scala_Pattern Matching - Fatal编程技术网

Scala的XML解析性能

Scala的XML解析性能,xml,performance,scala,pattern-matching,Xml,Performance,Scala,Pattern Matching,我在Scala中使用XML,在内存有限的系统中解析可以达到20MB的文件。我必须读取整个文件,并且必须从中提取所有数据。更具体地说,我必须读取的节点具有有限的属性和值 我想知道在性能方面最好的方法是什么(或者两者是否具有相同的性能)。我这样问是因为我不知道Scala是如何处理它的XML库的,我可能遗漏了一些细节 第一次进近 def firstApproach(root: Elem) = for { n <- root \ "node" } yield handleNodeAttrib

我在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)
}

那么,使用XPath方法处理所有文件是否比使用模式匹配和每个问题迭代一次(对于产量循环)有任何优势呢?

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

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

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

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

考虑到您的内存限制,您几乎肯定必须使用流式方法。使用流方法,您可以读取文件,提取感兴趣的部分,然后继续,这样就不会为文档中不感兴趣的部分积累额外的内存

请注意,如果要从文件中提取大量信息并将其保存在内存中,则实际上会否定流式处理的好处,因为您只需将所有数据保存在内存中。如果你发现自己处于这种情况,你有内存问题,考虑将数据流读入文件后,而不是保存在内存中。您可以将流视为XML上的一种转换。您将整个文档通读一次,转换(保留/更改/丢弃)您感兴趣的部分,并在转换完成后立即将其写出

scala.xml
现在,
scala.xml
包使用DOM风格的方法来处理xml,因此它可能不适合您。您的两个解决方案都基于此软件包。我建议使用支持XML流的Java库(我不知道有哪个Scala库支持XML流)

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

杰克逊
Jackson()支持基于流的XML处理,这可能比
javax.XML
中的API功能更丰富。确保您使用他们的流式API,因为他们也有基于DOM的API,这同样会给您带来内存问题。

20Mb现在并没有那么大。因此,这实际上取决于您对数据所做的操作。比较这两种方法的唯一可靠方法是测量它们的性能。我认为Jackson是一个JSON库而不是XML库?@MichaelKay最初是一个JSON库,但现在它也支持XML。(FWIW我的建议是直接使用SAX流式API,这样你绝对不会使用任何内存消耗API。)感谢关于处理XML的信息,非常有用@isomarte。感谢Imm和Michael的建议。