Java XOM规范化耗时太长
我有一个高达1GB的XML文件。我使用XOM来避免OutOfMemory异常 我需要规范化整个文档,但规范化需要很长时间,即使是1.5MB的文件 以下是我所做的: 我有这个示例XML文件,我通过复制Item节点来增加文档的大小Java XOM规范化耗时太长,java,xml,performance,canonicalization,xom,Java,Xml,Performance,Canonicalization,Xom,我有一个高达1GB的XML文件。我使用XOM来避免OutOfMemory异常 我需要规范化整个文档,但规范化需要很长时间,即使是1.5MB的文件 以下是我所做的: 我有这个示例XML文件,我通过复制Item节点来增加文档的大小 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <Packet id="some" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Packet id="some" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Head>
<PacketId>a34567890</PacketId>
<PacketHeadItem1>12345</PacketHeadItem1>
<PacketHeadItem2>1</PacketHeadItem2>
<PacketHeadItem3>18</PacketHeadItem3>
<PacketHeadItem4/>
<PacketHeadItem5>12082011111408</PacketHeadItem5>
<PacketHeadItem6>1</PacketHeadItem6>
</Head>
<List id="list">
<Item>
<Item1>item1</Item1>
<Item2>item2</Item2>
<Item3>item3</Item3>
<Item4>item4</Item4>
<Item5>item5</Item5>
<Item6>item6</Item6>
<Item7>item7</Item7>
</Item>
</List>
</Packet>
尽管这段代码适用于小文件,但在我的开发环境(4gb ram、64位、eclipse、windows)上,1.5mb文件的规范化部分大约需要7分钟
我们非常感谢任何指向此延迟原因的指针
另外,我需要规范化整个XML文档中的片段,以及整个文档本身。因此,使用文档本身作为参数对我不起作用
最佳
内部节点在列表中管理,并进行线性比较。
列表中的项目越多,“包含”将变慢
private final List nodes;
public boolean contains(Node node) {
return nodes.contains(node);
}
所以
- 尝试修改lib的代码,以使用HashMap保存节点
- 或者使用多线程来利用更多的CPU,如果您的XML可以拆分成小的XML
工具:JVisualVM 既然您希望整个文档序列化,您能替换
Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);
与
?
当给定要规范化的节点列表而不是根节点时,Canonicalizer
似乎会执行额外的工作(例如whunmr提到的nodes.contains()
调用)
如果这不起作用或者还不够,我会使用
规范化工具,并按照评测建议在那里进行优化。如果您愿意放弃XOM,我可能会找到解决您问题的方法。我的解决方案包括使用and
性能上的差异令人印象深刻,但我认为最好提供一个比较
在测试中,我使用了您在问题中提供的1.5MB的XML文件
XOM测试
XPath/Santuario测试
结果
下表以秒为单位列出了结果。试验进行了16次
╔═════════════════╦═════════╦═══════════╗
║ Test ║ Average ║ Std. Dev. ║
╠═════════════════╬═════════╬═══════════╣
║ XOM ║ 140.433 ║ 4.851 ║
╠═════════════════╬═════════╬═══════════╣
║ XPath/Santuario ║ 2.4585 ║ 0.11187 ║
╚═════════════════╩═════════╩═══════════╝
性能上的差异是巨大的,它与。使用XPath/Santuario的缺点是它们不像XOM那么简单
测试细节
机器:英特尔Core i5 4GB内存
SO:Debian 6.0 64位
Java:OpenJDK 1.6.01864位
XOM:1.2.8
ApacheSantuario:1.5.3
我觉得您的原始XML文件非常规范。什么是不规范的?谢谢你的回答。很有见地。你认为有更有效的方法规范化节点吗?不确定。如果您仍然想使用这个库,也许可以尝试使用HashMap来保存节点,从而修改库的代码。或者尝试其他LIB或方法。:)如果您的XML可以拆分成小的XML,那么您可以使用多线程来利用更多的CPU。因为目前你的应用程序在一个CPU中已经接近100%。使用更多的CPU显然可以减少应用程序的运行时间。实际上,我需要规范化XML文档中的片段。我意识到这个例子有点误导;我必须规范化列表节点。因此,我不一定希望规范化整个文档。
Nodes.contains is the most busy one
private final List nodes;
public boolean contains(Node node) {
return nodes.contains(node);
}
Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);
outputter.write(doc);
FileInputStream xmlFile = new FileInputStream("input.xml");
Builder builder = new Builder(false);
Document doc = builder.build(xmlFile);
FileOutputStream fos = new FileOutputStream("output.xml");
nu.xom.canonical.Canonicalizer outputter = new nu.xom.canonical.Canonicalizer(fos);
Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);
fos.close();
org.apache.xml.security.Init.init();
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse("input.xml");
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
org.w3c.dom.NodeList result = (org.w3c.dom.NodeList) xpath.evaluate("./descendant-or-self::node()|./@*", doc, XPathConstants.NODESET);
Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
byte canonXmlBytes[] = canon.canonicalizeXPathNodeSet(result);
IOUtils.write(canonXmlBytes, new FileOutputStream(new File("output.xml")));
╔═════════════════╦═════════╦═══════════╗
║ Test ║ Average ║ Std. Dev. ║
╠═════════════════╬═════════╬═══════════╣
║ XOM ║ 140.433 ║ 4.851 ║
╠═════════════════╬═════════╬═══════════╣
║ XPath/Santuario ║ 2.4585 ║ 0.11187 ║
╚═════════════════╩═════════╩═══════════╝