xalan api 的性能问题

问题描述

以下方法执行 10000 次迭代需要 33 秒(执行时间)。 CachedXPathAPI 来自 org.apache.xpath.CachedXPathAPI。 我正在使用 xalan-2.7.0.jar。 请任何人都可以帮助我如何减少执行时间。 如果我们增加负载,比如说 40000 次迭代,那么执行需要 10 分钟。整个方法 readxmlData 从 for 循环中调用

public static Hashtable<String,NodeList> readxmlData(CachedXPathAPI cashedXPath,org.w3c.dom.Document doc,String nodePath,int nodeInstance) throws Exception
{
    
    Hashtable<String,NodeList> input = null;

    try
    {
        NodeList rowNodes = cashedXPath.selectNodeList(doc,nodePath);
        // NodeList rowNodes = XPathAPI.selectNodeList( doc,nodePath);
        if (rowNodes == null)
            return null;

        if (rowNodes.getLength() <= 0)
            return null;

        Element rowNode = (Element) rowNodes.item(nodeInstance);
        if (rowNode == null)
            return null;

        NodeList rowElements = rowNode.getChildNodes();
        if (rowElements == null)
            return null;

        input = new Hashtable<String,NodeList>();

        for (int elementIndex = 0; elementIndex < rowElements.getLength(); elementIndex++)
        {
            Node rowElement = rowElements.item(elementIndex);

            if (rowElement.getNodeType() == Node.ELEMENT_NODE)
            {
                Element elem = (Element) rowElement;
                String name = elem.getNodeName();

                if (elem.hasChildNodes())
                {
                    NodeList child = elem.getChildNodes();
                    if (child != null)
                    {
                        input.put(name,child);
                    }
                } else if (elem.hasAttributes())
                {
                    input.put(name,(NodeList) rowElement);
                }
            }
        }

        return input;

    } catch (TransformerException ex)
    {
        throw new Exception("readxmlData (TransformerException): " + ex.getMessage());
    } catch (Exception ex)
    {
        throw new Exception("readxmlData (Exception): " + ex.getMessage());
    }
    
}

解决方法

首先,我会使用 HashMap - 但使方法 Map (**) 的签名。

你的方法的签名表明你可能正在做这样的事情(或者至少在循环中一遍又一遍地处理相同的 nodePath ...

readXMLData(cashedXPath,doc,nodePath,1);
readXMLData(cashedXPath,2);
readXMLData(cashedXPath,3);
readXMLData(cashedXPath,4);
readXMLData(cashedXPath,5);

如果是这种情况,那么第一个明显的事情是 selectNodeList 代码不必要地一遍又一遍地运行 - 它只需要为具有相同 {{1} 的一组行节点运行一次}.

nodePath

大概该调用必须访问文档的重要部分 - 它会评估 XPAth 的每个匹配项,即使您只使用第一个 [因此文档中的匹配项越多,这就越浪费] .

或者,如果这不重要,我会注释掉其他所有内容,看看这是否占您总处理时间的很多。如果在代码的其余部分花费了大量时间 - 执行相同的操作并将其分解。

另一个需要考虑的替代方案是使用了多大/多少内存......(**)每次该方法处理 NodeList rowNodes = cashedXPath.selectNodeList(doc,nodePath); 时,它都会将一些来自 DOM 的数据保存在地图中。如果您保留返回的内容 - 那么您将保留对有效临时数据结构的引用 - 所以内存使用量会越来越高,这可能会导致大量垃圾收集......一种解决方案 - 可能是增加内存应用程序可以运行的大小。另一种可能是找出您真正需要的 DOM 并将值保留在其中(例如不是 DOM 结构,但可能是叶内容 [但不是任何 DOM 对象 - 所以所有与 XPath 结果相关的临时结构可以被释放(和 GC)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...