Programmering

Forenkle XML-behandling med VTD-XML

Figur 3. Store XML-filer. Klik på miniaturebillede for at se billedet i fuld størrelse.

Otte år siden starten, har XML allerede startet som et åbent, semi-struktureret dataformat til lagring af data såvel som udveksling af data via internettet. På grund af sin enkelhed og menneskelige læsbarhed har XML set sin popularitet skyrocket blandt applikationsudviklere og er blevet en uundværlig del af virksomhedsarkitektur.

Selvom det er vanskeligt at opregne antallet af måder, XML bruges på, kan man være sikker på én ting: XML skal analyseres, før noget andet kan gøres. Faktisk er valg af den rigtige parser ofte en af ​​de første beslutninger, som virksomhedsudviklere skal tackle i deres projekter. Og igen og igen kommer beslutningen ned til de to populære XML-behandlingsmodeller: Document Object Model (DOM) og Simple API for XML (SAX).

Ved første øjekast virker de respektive styrker og svagheder ved DOM og SAX komplementære: DOM bygger objektgrafer i hukommelsen; SAX er begivenhedsbaseret og gemmer intet i hukommelsen. Så hvis dokumentstørrelsen er lille, og dataadgangsmønsteret er komplekst, er DOM vejen at gå; Ellers skal du bruge SAX.

Sandheden er dog aldrig så forenklet. Oftere end ikke er udviklere uvillige til at bruge SAX på grund af dets kompleksitet, men gør det stadig, fordi der ikke er noget andet levedygtigt valg. Ellers, hvis XML-filstørrelsen kun er lidt større end et par hundrede kilobyte, bliver DOMs hukommelsesoverhead og ydeevne-træk en hård vejspærring for applikationsudviklere, hvilket forhindrer dem i at nå deres projekters minimale præstationsmål.

Men er SAX virkelig så meget bedre? SAXs annoncerede parsingsydelse - typisk flere gange hurtigere end DOM - bedrager faktisk ofte. Det viser sig, at SAX-parsingens akavede, fremadrettede karakter ikke kun kræver ekstra implementeringsindsats, men også medfører sanktioner for ydeevne, når dokumentstrukturen kun bliver lidt kompleks. Hvis udviklere vælger ikke at scanne dokumentet flere gange, bliver de nødt til at buffere dokumentet eller oprette brugerdefinerede objektmodeller.

Uanset hvad lider ydeevnen, som eksemplificeret af Apache Axis. På sin FAQ-side hævder Axis, at han internt bruger SAX til at skabe en implementering, der har større ydelse, men alligevel bygger den sin egen objektmodel, der er ret DOM-lignende, hvilket resulterer i ubetydelige forbedringer i ydeevnen sammenlignet med sin forgænger (Apache SOAP). Derudover fungerer SAX ikke godt med XPath og kan generelt ikke drive XSLT-behandling (Extensible Stylesheet Language Transformation) -behandling. Så SAX-parsing skørt de reelle problemer med XML-behandling.

På udkig efter et lettere at bruge alternativ til SAX har et stigende antal udviklere henvendt sig til StAX (Streaming API til XML). Sammenlignet med SAX trækker StAX-parsere tokens fra XML-filer i stedet for at bruge tilbagekald. Selvom de mærkbart forbedrer anvendeligheden, er de grundlæggende problemer vedvarende - StAXs fremadrettede parsestil kræver stadig kedelig implementeringsindsats og sammen med det skjulte ydelsesomkostninger.

Bundlinjen: For at enhver XML-behandlingsmodel skal være bredt anvendelig, skal den præsentere den hierarkiske struktur for XML og intet mindre. Årsagen er, at XML er designet til at flytte komplekse data over internettet, og at formidle strukturel information er en iboende del af, hvad XML gør.

VTD-XML ændrer spillet

Antag, at vi skulle starte XML-behandling fra bunden for at overvinde de førnævnte problemer med DOM og SAX. Den nye model skal sandsynligvis have følgende egenskaber:

  • Tilfældig adgang i stand: Behandlingsmodellen skal give udvikleren mulighed for at navigere i en slags hierarkisk struktur enten manuelt eller bedre ved hjælp af XPath.
  • Høj ydeevne: Ydelsen skal være væsentligt bedre end DOM og SAX. Og ydeevnen skal være "ærlig", hvilket betyder at målingen skal omfatte den tid, der bruges på at opbygge den hierarkiske struktur.
  • Lavt hukommelsesforbrug: For at gøre behandlingsmodellen anvendelig til en bred vifte af scenarier og filstørrelser, skal den præsentere den fulde struktur af XML med et minimum af hukommelsesforbrug.

VTD-XML er designet til at opfylde disse mål og er den næste generation af open source XML-behandlingsmodel, der bringer grundlæggende og alsidige forbedringer i forhold til DOM og SAX. En nøgleoptimering af VTD-XML er ikke-ekstraktiv tokenisering. Internt bevarer VTD-XML i hukommelsen den intakte og udekodede XML-besked og repræsenterer tokens udelukkende baseret på en binær kodningsspecifikation kaldet Virtual Token Descriptor. En VTD-post er et 64-bit heltal, der koder tokenlængden, startforskydning, type og indlejringsdybde for et token i XML.

Her er lidt af historien om VTD-XML, hvis du er interesseret: Grundkonceptet blev udtænkt som en måde at porte XML-behandling på dedikeret hardware i form af FPGA eller ASIC for at aktivere netværksswitche og routere til at behandle XML indhold ved meget høje hastigheder. Senere besluttede VTD-XML-projektteamet at åbne VTD-XML, og den første udgivelse - af version 0.5 og implementeret i Java - fandt sted i maj 2004. Siden udgivelsen har VTD-XML gennemgået flere forbedringsrunder og modnet betydeligt. I version 0.8 blev C-versionen af ​​VTD-XML frigivet sammen med Java-versionen. Indbygget XPath-support blev introduceret i version 1.0 og udgivet i oktober 2005. Den nyeste version, version 1.5, har en omskrevet parsing-motor, der er mere modulær og højere.

Også introduceret i denne udgivelse er en funktion kaldet buffergenbrug. Grundideen er, at når en XML-applikation, der sidder bag en netværksforbindelse, skal behandle mange indkommende XML-dokumenter gentagne gange, kan applikationen faktisk genbruge hukommelsesbuffere, der er allokeret under den første behandlingskørsel. Med andre ord, tildel buffere en gang og brug dem mange, mange gange. Specifikt for VTD-XML tillader denne funktion fuldstændig eliminering af både objektgenerering og affaldsindsamlingsomkostninger (50-80 procent af omkostningerne i DOM og SAX) fra XML-behandling. Projektets websted indeholder de seneste software downloads og en grundig teknisk beskrivelse af VTD-XML.

Et hurtigt eksempel

For at give et indtryk af VTD-XML's programmeringsstil sammenligner denne artikel først kode ved hjælp af både VTD-XML og DOM til at analysere og navigere i en simpel XML-fil med navnet test.xml, hvis tekstindhold er vist nedenfor:

  Plæneklipper 1 148,95 

VTD-XML-versionen ser sådan ud:

import com.ximpleware. *; importer com.ximpleware.parser. *; import java.io. *;

public class use_vtd {public static void main (String [] args) {prøv {File f = new File ("test.xml"); FileInputStream fis = ny FileInputStream (f); byte [] ba = ny byte [(int) f.længde ()]; fis.read (ba); VTDGen vg = ny VTDGen (); vg.setDoc (ba); vg. parse (falsk); VTDNav vn = vg.getNav (); hvis (vn.matchElement ("purchaseOrder")) {System.out.println ("orderDate ==>" + vn.toString (vn.getAttrVal ("orderDate"))); if (vn.toElement (VTDNav.FIRST_CHILD, "item")) {if (vn.toElement (VTDNav.FIRST_CHILD)) {do {System.out.print (vn.toString (vn.getCurrentIndex ())); System.out.print ("==>");

System.out.println (vn.toString (vn.getText ())); } mens (vn.toElement (VTDNav.NEXT_SIBLING)); }}}} fangst (undtagelse e) {System.out.println ("undtagelse opstod ==>" + e); }}}

DOM-versionen af ​​den samme applikation er vist nedenfor:

import java.io. *; import org.w3c.dom. *; import org.w3c. *; import javax.xml.parsers. *; importere javax.xml.parsers.DocumentBuilder; importere javax.xml.parsers.DocumentBuilderFactory; importere javax.xml.parsers.FactoryConfigurationError; importere javax.xml.parsers.ParserConfigurationException; import org.w3c.dom. *; import org.xml.sax.SAXException;

public class use_dom {public static void main (String [] args) {try {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance (); DocumentBuilder parser = fabrik.newDocumentBuilder (); Dokument d = parser.parse ("test.xml"); Elementrod = d.getDocumentElement (); if (root.getNodeName (). CompareTo ("purchaseOrder") == 0) {System.out.println ("orderDate ==>" + root.getAttribute ("orderDate"));

Node n = root.getFirstChild (); if (n! = null) {do {if (n.getNodeType () == Node.ELEMENT_NODE && n.getNodeName (). comparTo ("item") == 0) {Node n2 = n.getFirstChild (); if (n2! = null) {do {if (n2.getNodeType () == Node.ELEMENT_NODE) ​​{System.out.println (n2.getNodeName () + "==>" + n2.getFirstChild (). getNodeValue ( )); }} mens ((n2 = n2.getNextSibling ())! = null); }}} mens ((n = n.getNextSibling ())! = null); }}} fangst (Undtagelse e) {System.out.println ("undtagelse opstod ==>" + e); }}}

Som illustreret i kodeeksempler ovenfor navigerer VTD-XML i XML-hierarkiet ved hjælp af en markørbaseret API. I modsætning hertil navigerer DOM API i hierarkiet ved at anmode om objektreferencer. Besøg VTD-XML-projektets websted for mere tekniske materialer og kodeeksempler, der forklarer VTD-XML i dybden.

Benchmarking af VTD-XML

Lad os derefter sammenligne VTD-XML's ydeevne og hukommelsesforbrug med nogle populære XML-parsere. Det skal bemærkes, at de fleste artikler, der indeholder benchmark-numre, såsom "XML-dokumenter på flugt" af Dennis Sosnoski (JavaWorld, April 2002), er fra flere år siden. Siden da følger bedre og hurtigere hardware Moores lov og bliver billigere end nogensinde. Samtidig har XML-parsing og den virtuelle Java-maskine ikke stået stille - de har set forbedringer på mange nøgleområder.

Testopsætning

Testplatformen er en Sony VAIO bærbar computer udstyret med en Pentium M 1,7 GHz processor (2 MB integreret L2 cache) og 512 MB DDR2 RAM. Den forreste bus er uret ved 400 MHz. Operativsystemet er Windows XP Professional Edition med servicepakke 2. JVM er version 1.5.0_06.

Benchmarket tester de nyeste versioner af følgende XML-parsere:

  • Xerces DOM 2.7.1, med og uden udskudt nodeudvidelse
  • Xerces SAX 2.7.1
  • Piccolo SAX 1.04
  • XPP3 1.1.3.4.O
  • VTD-XML 1.5, med og uden buffergenbrug

Jeg valgte en stor samling af XML-dokumenter i forskellige størrelser og strukturelle kompleksiteter til testen. Afhængig af filstørrelsen er testdokumenterne grupperet i tre kategorier. Små filer er mindre end 10 KB i størrelse. Mellemstore filer er mellem 10 KB og 1 MB. Filer større end 1 MB betragtes som store.

Serveren JVM blev brugt til alle ydeevnemålinger for at opnå den maksimale ydeevne. I disse tests slog benchmark-programmerne først gennem parsing eller navigationsrutiner adskillige gange, så JVM udførte den dynamiske, just-in-time optimering af byte-koden, før gennemsnittet af udførelsen af ​​efterfølgende iterationer som de endelige resultater. For at reducere timingvariation på grund af disk I / O læser benchmark-programmerne alle XML-filer i hukommelsesbuffere inden testkørslerne.

Bemærk: Interesserede læsere kan downloade benchmark-programmet fra Resources.

Analyse af gennemløbs sammenligninger

Dette afsnit præsenterer XML-parseringsydelsen i både latenstid og gennemstrømning. Bemærk, at mens VTD-XML og DOM er direkte sammenlignelige, er det ikke rimeligt at sammenligne VTD-XML med SAX eller Pull, fordi de ikke bygger nogen hierarkisk struktur i hukommelsen. Så ydeevne for SAX og Pull fungerer kun som et ekstra referencepunkt.

Gennemstrømning

Latency sammenligninger

Tabel 1. Små filer

Filnavn / størrelseVTD-XML (ms)VTD-XML-buffergenbrug (ms)SAX (ms)DOM (ms)DOM udsat (ms)Piccolo (ms)Træk (ms)
soap2.xml (1727 bytes)0.04460.03460.07820.11220.162250.0920.066
nav_48_0.xml (4608 bytes)0.10540.09280.2660.370.3850.27840.1742
cd_catalog.xml (5035 bytes)0.1180.1080.190.3480.40.20.214
nav_63_0.xml (6848 bytes)0.1490.1350.3540.5130.5570.4840.242
nav_78_0.xml (6920 bytes)0.1530.1420.37040.5880.520.420.29

Tabel 2. Medium XML-filer