优化DOM和XPath Java代码

3

我的代码太慢了,但我不确定如何改进它。从磁盘读取 1k 文件到 DOM 大约需要 20 毫秒,这可能取决于磁盘的情况而可以接受,但接下来对 xpath 语句进行处理需要另外 20 毫秒,这是远远太长的时间。以下是一些带有时间注释的示例代码,请问如何改进代码?

这发生在构建时:

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = this.dbFactory.newDocumentBuilder(); 
XPathExpression[] ex = new XPathExpression[]{about 30 different expressions}
XPathExpression mainEx =xPath.compile("/rootElement/firstLevel/secondLevel");

那么这段代码:

Document doc = this.dBuilder.parse("somefile.xml");
//took 20 ms until here
NodeList nodes = (NodeList) mainEx .evaluate,doc, XPathConstants.NODESET);
 //took another 20 ms until here !!!
    for (int i = 0; i < nodes.getLength(); i++) {
    Node n = nodes.item(i);
    for (XPathExpression e:ex) {
         String v = (String) e.evaluate(n, XPathConstants.STRING);
        if (v != null) {
            System.out.println(v);
        }
    }
    }
    //this only takes 5 ms

可能与 https://dev59.com/fmw15IYBdhLWcg3w4_tL 相关。 - Lukas Eder
切换到VTD-XML,你的问题将会消失。 - vtd-xml-author
2个回答

5
您可能正在遭受我在此记录的问题:Java XPath(Apache JAXP实现)性能

基本上,您应该添加这些JVM参数来大幅提高Xalan的XPath实现速度:

-Dorg.apache.xml.dtm.DTMManager=
  org.apache.xml.dtm.ref.DTMManagerDefault

或者

-Dcom.sun.org.apache.xml.internal.dtm.DTMManager=
  com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault

4
你应该预编译XPath表达式到一个XPathExpression,使用XPath.compile。然后调用XPathExpression.evaluate
如果你需要多次执行该表达式,则这将节省时间。我假设这是情况,否则20毫秒不应成问题。
编辑:如评论中所述,此问题包含更多信息,包括JVM参数。

我把所有东西都改成了预编译表达式,但实际上并没有显著提高性能,可能只有几毫秒。有没有更快的构建DOM或更快的XPath评估器的方法? - Franz Kafka
@Franz,所以评估之前编译的表达式需要近20毫秒?你使用的是哪个实现(我认为getClass会告诉你)?这个问题表明Xalan 2.7.1是最快的(在测试中),并提供了一个JVM参数进行优化。 - Matthew Flaschen
com.sun.org.apache.xpath.internal.jaxp.XPathImpl,我应该切换吗? - Franz Kafka
@Franz,我相信那是捆绑的Xalan。但我不确定是哪个版本。请尝试我链接问题中提到的JVM参数。 - Matthew Flaschen
不完美,但它只花费了约8毫秒的时间。但是仍在评估这样一个基本的xPath使用需要10毫秒。 - Franz Kafka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接