Java XPath (Apache JAXP-Implementierung) Leistung
HINWEIS: Wenn Sie dieses Problem als gut, bitte upvote es auf Apache-JIRA:
Ich habe kommen zu einer erstaunlichen Schlussfolgerung, dass diese:
Element e = (Element) document.getElementsByTagName("SomeElementName").item(0);
String result = ((Element) e).getTextContent();
Scheint eine unglaubliche 100x schneller als dies:
//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);
Ich bin mit dem JVM-Standard-Implementierung von JAXP:
org.apache.xpath.jaxp.XPathFactoryImpl
org.apache.xpath.jaxp.XPathImpl
Bin ich wirklich verwirrt, denn es ist leicht zu sehen, wie JAXP optimieren konnten, die über XPath-Abfrage tatsächlich auszuführen eine einfache getElementsByTagName()
statt. Aber es scheint nicht zu tun. Dieses problem beschränkt sich auf etwa 5-6 Häufig verwendete XPath-Aufrufe, sind abstrahiert und verborgen durch eine API. Solche Abfragen beinhalten einfache Pfade (z.B. /a/b/c
keine Variablen, Bedingungen) gegen eine immer verfügbare DOM-Dokument nur. Also, wenn eine Optimierung durchgeführt werden kann, wird es sehr einfach zu erreichen.
Meine Frage: Ist XPath ist Langsamkeit eine anerkannte Tatsache, oder bin ich mit Blick auf etwas? Gibt es eine bessere (schnellere) Umsetzung? Oder sollte ich einfach vermeiden XPath-insgesamt, für einfache Abfragen?
InformationsquelleAutor der Frage Lukas Eder | 2011-06-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe gedebuggt und profilierten meinem test-Fall und Xalan/JAXP im Allgemeinen. Ich identifizieren konnte, die großen major problem in
Es kann gesehen werden, dass jeder der 10k test XPath-Auswertungen führten zu der classloader versucht, Suche die
DTMManager
- Instanz in einer Art Standard-Konfiguration. Diese Konfiguration wird nicht in den Speicher geladen, sondern zugreifen zu jeder Zeit. Darüber hinaus ist dieser Zugang scheint zu sein, geschützt durch eine Sperre auf derObjectFactory.class
selbst. Wenn der Zugriff fehlschlägt (standardmäßig), dann wird die Konfiguration geladen wird, diexalan.jar
DateiKonfigurationsdatei. Jedes mal!:
Glück, dieses Verhalten kann überschrieben werden, indem eine JVM-parameter wie diese:
oder
Den oben genannten arbeiten, denn dadurch können die umgehen die teure Arbeit in
lookUpFactoryClassName()
wenn der factory-Klasse name die Standardeinstellung ist sowieso:So, hier ist eine Verbesserung der performance im überblick für 10k aufeinander folgenden XPath-Auswertungen von
//SomeNodeName
gegen einen 90k XML-Datei (gemessen mitSystem.nanoTime()
:beachten Sie, dass der benchmark war sehr primitiv. es kann gut sein, dass Sie Ihre eigenen Benchmarks zeigen, dass die sächsischen übertrifft xalan
Ich eingereicht habe dies als bug und den Xalan Jungs von Apache:
https://issues.apache.org/jira/browse/XALANJ-2540
InformationsquelleAutor der Antwort Lukas Eder
Nicht eine Lösung, sondern ein Zeiger auf das Haupt-problem:
Die langsamste Teil des Prozesses bei der Auswertung eines xpath in Bezug auf einen beliebigen Knoten ist die Zeit, die die DTM-manager, suchen Sie nach dem Knoten Griff:
http://javasourcecode.org/html/open-source/jdk/jdk-6u23/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.html#getHandleOfNode%28org.w3c.dom.Node%29
Wenn der Knoten in Frage, die am Ende des Dokuments, kann es am Ende zu Fuß den gesamten Baum zu finden, den Knoten in Frage, die für jede Abfrage.
Dies erklärt, warum der hack, um Waisen aus der Ziel-Knoten funktioniert.
Es sollte ein Weg sein, um diesen cache lookups, aber an dieser Stelle kann ich nicht sehen, wie.
InformationsquelleAutor der Antwort Robbie Matthews
Ihre Frage zu beantworten, vtd-xml ist schneller als Jaxen oder Xalan) (ich würde sagen durchschnittlich
10x und 60x berichtet wurde...
InformationsquelleAutor der Antwort vtd-xml-author