xalan api 的性能问题
Performance issue with xalan api
以下方法执行 10000 次迭代需要 33 秒(执行时间)。
CachedXPathAPI 来自 org.apache.xpath.CachedXPathAPI。
我正在使用 xalan-2.7.0.jar。
请任何人在这里提供帮助,我怎样才能减少执行时间。
如果我们增加负载,比如说 40000 次迭代,那么执行需要 10 分钟。整个方法 readXMLData 从 for loop
调用
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, doc, nodePath, 2);
readXMLData(cashedXPath, doc, nodePath, 3);
readXMLData(cashedXPath, doc, nodePath, 4);
readXMLData(cashedXPath, doc, nodePath, 5);
如果是这种情况,那么第一个显而易见的事情是 selectNodeList
代码不必要地一遍又一遍地被 运行 - 它只需要为一组 运行 一次具有相同 nodePath
.
的行节点数
NodeList rowNodes = cashedXPath.selectNodeList(doc, nodePath);
据推测,该调用必须命中文档的重要部分 - 它会评估 XPAth 的每个匹配项,即使您只使用第一个 [因此文档中的匹配项越多,这个越浪费是].
或者,如果这不重要,我会注释掉其他所有内容,看看这是否占了您的总处理时间。如果在其余代码上花费了大量时间 - 做同样的事情并将其分解。
另一个要考虑的替代方案是使用了多大/多少内存...(**) 每次该方法处理 rowElements
时,它都会在映射中保留来自 DOM。如果您保留返回的内容 - 那么您将保留对有效临时数据结构的引用 - 因此内存使用量会不断增加,这可能会导致大量垃圾收集......一种解决方案 - 可能是增加内存应用程序的大小可以 运行 in.. 另一个可能是计算出你真正需要的 DOM 的内容并将值保留在其中(例如,不是 DOM 结构,但可能是叶子内容 [但不是任何 DOM 对象 - 因此可以释放(和 GC'd)与 XPath 结果相关的所有临时结构。
以下方法执行 10000 次迭代需要 33 秒(执行时间)。 CachedXPathAPI 来自 org.apache.xpath.CachedXPathAPI。 我正在使用 xalan-2.7.0.jar。 请任何人在这里提供帮助,我怎样才能减少执行时间。 如果我们增加负载,比如说 40000 次迭代,那么执行需要 10 分钟。整个方法 readXMLData 从 for loop
调用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, doc, nodePath, 2);
readXMLData(cashedXPath, doc, nodePath, 3);
readXMLData(cashedXPath, doc, nodePath, 4);
readXMLData(cashedXPath, doc, nodePath, 5);
如果是这种情况,那么第一个显而易见的事情是 selectNodeList
代码不必要地一遍又一遍地被 运行 - 它只需要为一组 运行 一次具有相同 nodePath
.
NodeList rowNodes = cashedXPath.selectNodeList(doc, nodePath);
据推测,该调用必须命中文档的重要部分 - 它会评估 XPAth 的每个匹配项,即使您只使用第一个 [因此文档中的匹配项越多,这个越浪费是].
或者,如果这不重要,我会注释掉其他所有内容,看看这是否占了您的总处理时间。如果在其余代码上花费了大量时间 - 做同样的事情并将其分解。
另一个要考虑的替代方案是使用了多大/多少内存...(**) 每次该方法处理 rowElements
时,它都会在映射中保留来自 DOM。如果您保留返回的内容 - 那么您将保留对有效临时数据结构的引用 - 因此内存使用量会不断增加,这可能会导致大量垃圾收集......一种解决方案 - 可能是增加内存应用程序的大小可以 运行 in.. 另一个可能是计算出你真正需要的 DOM 的内容并将值保留在其中(例如,不是 DOM 结构,但可能是叶子内容 [但不是任何 DOM 对象 - 因此可以释放(和 GC'd)与 XPath 结果相关的所有临时结构。