java - Java XPath ( Apache JAXP实现) 性能

  显示原文与译文双语对照的内容
63 0

注意:如果你也遇到这里问题,请在 Apache JIRA上将它的添加:

https://issues.apache.org/jira/browse/XALANJ-2540

我得到了一个惊人的结论:

Element e = (Element) document.getElementsByTagName("SomeElementName").item(0);
String result = ((Element) e).getTextContent();

似乎比这更快的100x:

//Accounts for 30%, can be cached
XPathFactory factory = XPathFactory.newInstance();
//Negligible
XPath xpath = factory.newXPath();
//Negligible
XPathExpression expression = xpath.compile("//SomeElementName");
//Accounts for 70%
String result = (String) expression.evaluate(document, XPathConstants.STRING);

我使用的是JAXP的缺省jvm实现:

org.apache.xpath.jaxp.XPathFactoryImpl
org.apache.xpath.jaxp.XPathImpl

我真的很困惑,因为很容易看到JAXP如何优化上面的XPath查询来实际执行简单的getElementsByTagName()但这似乎并不意味着。这个问题被限制在大约 5 -6的XPath调用中,这些调用被API抽象和隐藏。这些查询涉及简单路径( 比如 。/a/b/c,只针对始终可用的DOM文档,没有变量,条件。因此,如果可以进行优化,那么就很容易实现。

我的问题:xpath的慢度是接受事实,还是我忽略了?是否有更好的( 更快) 实现?还是我应该完全避免 XPath,因为简单的查询?

时间:原作者:0个回答

103 0

我已经对测试用例和 xalan/jaxp进行了调试和概要分析。我发现了主要的问题

org.apache.xml.dtm.ObjectFactory.lookUpFactoryClassName()

可以看到,每个 10k 测试XPath评估都导致类加载器试图在某种默认配置中查找 DTMManager 实例。这里配置未加载到内存中,但每次都被访问。这里外,这个访问似乎是 protected的锁的ObjectFactory.class 本身。访问失败( 默认情况) 时,将从 xalan.jar 文件加载配置

META-INF/service/org.apache.xml.dtm.DTMManager

配置文件每次收费 !

JProfiler profiling results

,可以通过像这样指定一个JVM参数来覆盖这个行为:

-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

上面的工作,因为这将允许在 lookUpFactoryClassName()的工厂名称为默认值时绕过中的昂贵工作:

//Code from com.sun.org.apache.xml.internal.dtm.ObjectFactory
static String lookUpFactoryClassName(String factoryId,
 String propertiesFilename,
 String fallbackClassName) {
 SecuritySupport ss = SecuritySupport.getInstance();
 try {
 String systemProp = ss.getSystemProperty(factoryId);
 if (systemProp!= null) { 
//Return early from the method
 return systemProp;
 }
 } catch (SecurityException se) {
 }
//[...]"Heavy" operations later

下面是针对 10k 个XML文件( 用测量的90k 个XML文件)的连续XPath评估的性能改进概览:

measured library : Xalan 2.7.0 | Xalan 2.7.1 | Saxon-HE 9.3 | jaxen 1.1.3
--------------------------------------------------------------------------------
without optimisation : 10400ms | 4717ms | | 25500ms
reusing XPathFactory : 5995ms | 2829ms | |
reusing XPath : 5900ms | 2890ms | |
reusing XPathExpression : 5800ms | 2915ms | 16000ms | 25000ms
adding the JVM param : 1163ms | 761ms | n/a |

注意,基准测试是非常原始的。很可能你自己的基准会显示saxon优于 xalan 。

我把它作为一个 Bug 归档给Apache的Xalan人员:

https://issues.apache.org/jira/browse/XALANJ-2540

原作者:
...