Apache-camel Xpathbuilder 性能
Apache-camel Xpathbuilder performance
我有以下问题。我设置了一个 camel -project 来解析某些 xml 文件。我必须选择从文件中取出某些节点。
我有两个文件,大小分别为 246kb 和 347kb。在上面给出的示例中,我正在提取一对 250 个节点的父子节点。
默认工厂是时代。对于 246kb 的文件,需要 77 秒和 106 秒。我想提高性能,所以切换到撒克逊,时间如下 47 秒和 54 秒。我能够将时间缩短至少一半。
是否可以进一步缩短时间,我可以使用的任何其他工厂或优化将不胜感激。
我正在使用 XpathBuilder 删除 xpath。这是一个例子。是否有可能不必重复创建 XpathBuilder,似乎必须为每个 xpath 构建它,我会有一个实例并不断将 xpath 泵入其中,也许它会进一步提高性能。
return XPathBuilder.xpath(nodeXpath)
.saxon()
.namespace(Consts.XPATH_PREFIX, nameSpace)
.evaluate(exchange.getContext(), exchange.getIn().getBody(String.class), String.class);
根据 Michael 的评论添加更多详细信息。所以我有点加入他们,将通过下面的示例变得清楚。我将它们组合成 json。
所以我们开始吧,假设我们有以下第一条和第二条路径的映射。
pData.tinf.rexd: bm:Document/bm:xxxxx/bm:PmtInf[{0}]/bm:ReqdExctnDt/text()
pData.tinf.pIdentifi.instId://bm:Document/bm:xxxxx/bm:PmtInf[{0}]/bm:CdtTrfTxInf[{1}]/bm:PmtId/bm:InstrId/text()
这将导致 json 如下
pData:{
tinf: {
rexd: <value_from_xml>
}
pIdentifi:{
instId: <value_from_xml>
}
}
如果没有看到您的实际 XPath 表达式很难说,但考虑到文件大小和执行时间,我的猜测是您正在执行一个连接,它作为笛卡尔积天真地执行,即 O(n* m) 性能。可能有一些方法可以重组它以获得对数性能,但细节决定成败。 Saxon-EE 非常擅长自动优化连接查询;如果没有,通常有手动完成的方法——尽管 XSLT 比 XPath 提供更多选项(例如使用 xsl:key
或 xsl:merge
)。
实际上我能够将时间缩短到 10 秒。我正在使用阿帕奇骆驼。所以我在那里添加了线程,以便可以在单独的线程中读取多个文件。一旦文件被读取,它就会根据必须遍历的节点的长度进行串行操作。我意识到这里没有必要串行,所以引入了 parrallelStream,现在它有足够的能力。需要注意的一件事是不要有线程激增,因为这会降低性能。所以我尝试将线程数限制为运行机器上内核数的两倍或三倍。
我有以下问题。我设置了一个 camel -project 来解析某些 xml 文件。我必须选择从文件中取出某些节点。
我有两个文件,大小分别为 246kb 和 347kb。在上面给出的示例中,我正在提取一对 250 个节点的父子节点。
默认工厂是时代。对于 246kb 的文件,需要 77 秒和 106 秒。我想提高性能,所以切换到撒克逊,时间如下 47 秒和 54 秒。我能够将时间缩短至少一半。
是否可以进一步缩短时间,我可以使用的任何其他工厂或优化将不胜感激。
我正在使用 XpathBuilder 删除 xpath。这是一个例子。是否有可能不必重复创建 XpathBuilder,似乎必须为每个 xpath 构建它,我会有一个实例并不断将 xpath 泵入其中,也许它会进一步提高性能。
return XPathBuilder.xpath(nodeXpath)
.saxon()
.namespace(Consts.XPATH_PREFIX, nameSpace)
.evaluate(exchange.getContext(), exchange.getIn().getBody(String.class), String.class);
根据 Michael 的评论添加更多详细信息。所以我有点加入他们,将通过下面的示例变得清楚。我将它们组合成 json。 所以我们开始吧,假设我们有以下第一条和第二条路径的映射。
pData.tinf.rexd: bm:Document/bm:xxxxx/bm:PmtInf[{0}]/bm:ReqdExctnDt/text() pData.tinf.pIdentifi.instId://bm:Document/bm:xxxxx/bm:PmtInf[{0}]/bm:CdtTrfTxInf[{1}]/bm:PmtId/bm:InstrId/text()
这将导致 json 如下
pData:{
tinf: {
rexd: <value_from_xml>
}
pIdentifi:{
instId: <value_from_xml>
}
}
如果没有看到您的实际 XPath 表达式很难说,但考虑到文件大小和执行时间,我的猜测是您正在执行一个连接,它作为笛卡尔积天真地执行,即 O(n* m) 性能。可能有一些方法可以重组它以获得对数性能,但细节决定成败。 Saxon-EE 非常擅长自动优化连接查询;如果没有,通常有手动完成的方法——尽管 XSLT 比 XPath 提供更多选项(例如使用 xsl:key
或 xsl:merge
)。
实际上我能够将时间缩短到 10 秒。我正在使用阿帕奇骆驼。所以我在那里添加了线程,以便可以在单独的线程中读取多个文件。一旦文件被读取,它就会根据必须遍历的节点的长度进行串行操作。我意识到这里没有必要串行,所以引入了 parrallelStream,现在它有足够的能力。需要注意的一件事是不要有线程激增,因为这会降低性能。所以我尝试将线程数限制为运行机器上内核数的两倍或三倍。