Pojednostavite XML obradu s VTD-XML

Slika 3. Velike XML datoteke. Kliknite na sličicu za prikaz slike u punoj veličini.

Osam godina od svog osnivanja, XML se već pokrenuo kao otvoreni, polustrukturirani format podataka za pohranu podataka, kao i razmjenu podataka putem weba. Zbog svoje jednostavnosti i čitljivosti, XML je vidio svoju popularnost u porastu među programerima aplikacija i postao je neizostavan dio poslovne arhitekture.

Iako je teško nabrojati broj načina na koji se XML koristi, u jedno možemo biti sigurni: XML se mora raščlaniti prije nego što se bilo što drugo može učiniti. Zapravo je odabir pravog parsera često jedna od prvih odluka s kojima se programeri poduzeća moraju uhvatiti u koštac u svojim projektima. I opet i opet, ta se odluka svodi na dva popularna modela obrade XML: objektni model dokumenta (DOM) i jednostavni API za XML (SAX).

Na prvi pogled, odgovarajuće snage i slabosti DOM-a i SAX-a čine se komplementarnima: DOM izrađuje grafove objekata u memoriji; SAX se temelji na događajima i ne pohranjuje ništa u memoriju. Dakle, ako je veličina dokumenta mala, a obrazac pristupa podacima složen, DOM je pravi put; u suprotnom koristite SAX.

Međutim, istina nikada nije tako pojednostavljena. Češće nego ne, programeri ne žele koristiti SAX zbog njegove složenosti, no još uvijek čine jer nije dostupan nijedan drugi održiv izbor. Inače, ako je veličina XML datoteke tek malo veća od nekoliko stotina kilobajta, DOM-ovi troškovi memorije i povlačenje performansi postaju teška prepreka za programere, onemogućavajući im da ispune minimalne ciljeve izvedbe svojih projekata.

No, je li SAX stvarno toliko bolji? SAX-ove reklamirane performanse raščlanjivanja - obično nekoliko puta brže od DOM-a - zapravo često obmanjuju. Ispostavilo se da neugodna, samo naprijed raščlanjivanje SAX-a ne zahtijeva samo dodatni napor u implementaciji, već iziskuje i kazne za izvedbu kad struktura dokumenta postane tek malo složena. Ako programeri odluče ne skenirati dokument više puta, morat će ga međuspremiti ili izraditi prilagođene objektne modele.

U svakom slučaju, performanse trpe, što ilustrira Apache Axis. Na svojoj stranici s čestim pitanjima Axis tvrdi da interno koristi SAX za stvaranje implementacije s boljim performansama, ali ipak gradi vlastiti objektni model koji je prilično DOM-ov, što rezultira zanemarivim poboljšanjima performansi u usporedbi s prethodnikom (Apache SOAP). Uz to, SAX ne radi dobro s XPathom i općenito ne može pokretati XSLT (Extensible Stylesheet Language Transformation) obradu. Dakle, SAX raščlanjivanje sučeljava stvarne probleme XML obrade.

U potrazi za lakšom alternativom za SAX, sve veći broj programera okrenuo se StAX-u (Streaming API za XML). U usporedbi sa SAX-om, analizatori StAX povlače tokene iz XML datoteka umjesto da koriste povratne pozive. Iako oni znatno poboljšavaju iskoristivost, osnovna pitanja i dalje postoje - StAX-ov stil raščlanjivanja samo unaprijed i dalje zahtijeva dosadan napor u implementaciji i, zajedno s tim, skrivene troškove izvedbe.

Dno crta: Da bi bilo koji XML model obrade bio široko koristan, on mora predstavljati hijerarhijsku strukturu XML-a i ništa manje. Razlog je taj što je XML dizajniran za premještanje složenih podataka preko weba, a prenošenje strukturnih informacija sastavni je dio onoga što XML radi.

VTD-XML mijenja igru

Pretpostavimo da smo započeli XML obradu od nule kako bismo prevladali gore spomenute probleme s DOM-om i SAX-om. Novi bi model vjerojatno trebao imati sljedeća svojstva:

  • Mogućnost slučajnog pristupa: Model obrade treba omogućiti programeru da se kreće nekom vrstom hijerarhijske strukture bilo ručno ili, bolje, pomoću XPath-a.
  • Visoke performanse: Performanse bi trebale biti znatno bolje od DOM-a i SAX-a. A izvedba bi trebala biti "iskrena", što znači da mjerenje mora uključivati ​​vrijeme utrošeno na izgradnju hijerarhijske strukture.
  • Niska potrošnja memorije: da bi model obrade bio primjenjiv na širok raspon scenarija i veličina datoteka, on mora predstaviti potpunu strukturu XML-a s minimalnom količinom memorije.

Dizajniran da ispuni te ciljeve, VTD-XML je sljedeća generacija XML modela obrade otvorenog koda koji donosi temeljna i sveobuhvatna poboljšanja u odnosu na DOM i SAX. Jedna od ključnih optimizacija VTD-XML je neestraktivna tokenizacija. Interno, VTD-XML zadržava u memoriju intaktni i undecoded XML poruke, a predstavlja tokeni isključivo na temelju binarno kodiranje specifikaciji naziva V irtual T oken D escriptor. VTD zapis je 64-bitni cijeli broj koji kodira duljinu tokena, početni pomak, tip i dubinu gniježđenja tokena u XML-u.

Evo malo povijesti VTD-XML u slučaju da vas zanima: Osnovni koncept zamišljen je kao način prijenosa XML obrade na namjenski hardver, u obliku FPGA ili ASIC, kako bi se mrežnim preklopnicima i usmjerivačima omogućila obrada XML-a. sadržaj pri vrlo velikim brzinama. Kasnije je projektni tim VTD-XML odlučio otvoriti VTD-XML otvorenog koda, a početno izdanje - verzije 0.5 i implementirano u Javi - dogodilo se u svibnju 2004. Od tog izdanja VTD-XML je prošao nekoliko krugova poboljšanja i sazrio znatno. U verziji 0.8 objavljena je C verzija VTD-XML zajedno s inačicom Java. Ugrađena podrška za XPath predstavljena je u verziji 1.0 i objavljena u listopadu 2005. Najnovije izdanje, verzija 1.5, sadrži prepisani mehanizam za raščlanjivanje koji je modularniji i ima veće performanse.

U ovo izdanje također je uvedena značajka koja se naziva ponovna upotreba međuspremnika. Osnovna je ideja da kada XML aplikacija koja sjedi iza mrežne veze mora ponavljati obradu mnogih dolaznih XML dokumenata, aplikacija zapravo može ponovno koristiti međuspremnike memorije dodijeljene tijekom prvog izvođenja obrade. Drugim riječima, dodijelite međuspremnike jednom i upotrijebite ih puno, puno puta. Specifična za VTD-XML, ova značajka omogućuje potpuno uklanjanje i stvaranja predmeta i troškova odvoza smeća (50-80 posto režijskih troškova u DOM-u i SAX-u) iz XML obrade. Web stranica projekta sadrži najnovija preuzimanja softvera i detaljni tehnički opis VTD-XML.

Brzi primjer

Da biste stekli dojam o programskom stilu VTD-XML, ovaj članak prvo uspoređuje kod koristeći VTD-XML i DOM za raščlanjivanje i kretanje kroz jednostavnu XML datoteku nazvanu test.xml, čiji je tekstualni sadržaj prikazan u nastavku:

  Lawnmower 1 148.95  

Verzija VTD-XML izgleda ovako:

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

public class use_vtd { public static void main(String[] args){ try{ File f = new File("test.xml"); FileInputStream fis = new FileInputStream(f); byte[] ba = new byte[(int)f.length()]; fis.read(ba); VTDGen vg = new VTDGen(); vg.setDoc(ba); vg.parse(false); VTDNav vn = vg.getNav(); if (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())); } while(vn.toElement(VTDNav.NEXT_SIBLING)); } } } } catch (Exception e){ System.out.println("exception occurred ==>"+e); } } }

DOM verzija iste aplikacije prikazana je u nastavku:

import java.io.*; import org.w3c.dom.*; import org.w3c.*; import javax.xml.parsers.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import 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 = factory.newDocumentBuilder(); Document d= parser.parse("test.xml"); Element root = 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().compareTo("item")==0){ Node n2 = n.getFirstChild(); if (n2!=null){ do { if (n2.getNodeType() == Node.ELEMENT_NODE){ System.out.println( n2.getNodeName() + "==>" + n2.getFirstChild().getNodeValue() ); } }while((n2=n2.getNextSibling())!=null); } } }while ((n=n.getNextSibling()) != null ); } } } catch (Exception e){ System.out.println("exception occurred ==>"+e); } } }

Kao što je prikazano u gornjim primjerima koda, VTD-XML se kreće XML hijerarhijom koristeći API zasnovan na kurzoru. Suprotno tome, DOM API kreće hijerarhijom tražeći reference na objekt. Molimo posjetite web stranicu projekta VTD-XML za više tehničkih materijala i primjere koda koji detaljno objašnjavaju VTD-XML.

Benchmarking VTD-XML

Dalje, usporedimo izvedbu VTD-XML i upotrebu memorije s nekim popularnim XML parserima. Treba napomenuti da je većina članaka koji sadrže referentne brojeve, poput "XML dokumenata u bijegu" Dennisa Sosnoskog ( JavaWorld , travanj 2002.), od prije nekoliko godina. Od tada, bolji i brži hardver slijedi Mooreov zakon i postaje jeftiniji nego ikad. Istodobno, XML raščlanjivanje i Java virtualni stroj ne stoje mirno - vidjeli su poboljšanja u mnogim ključnim područjima.

Postavljanje testa

Ispitna platforma je Sony VAIO prijenosno računalo opremljeno procesorom Pentium M 1,7 GHz (2 MB integrirane L2 predmemorije) i 512 MB DDR2 RAM-a. Prednja sabirnica radi na 400 MHz. OS je Windows XP Professional Edition sa servisnim paketom 2. JVM je verzije 1.5.0_06.

The benchmark tests the latest versions of the following XML parsers:

  • Xerces DOM 2.7.1, with and without deferred node expansion
  • Xerces SAX 2.7.1
  • Piccolo SAX 1.04
  • XPP3 1.1.3.4.O
  • VTD-XML 1.5, with and without buffer reuse

I selected a large collection of XML documents of varying sizes and structural complexities for the test. Depending on the file size, the test documents are grouped into three categories. Small files are less than 10 KB in size. Mid-sized files are between 10 KB and 1 MB. Files larger than 1 MB are considered big.

The server JVM was used for all performance measurements to obtain the peak performance. In those tests, the benchmark programs first looped through the parsing or navigation routines numerous times so that the JVM performed the dynamic, just-in-time optimization of the byte code, before averaging the performance of subsequent iterations as the final results. To reduce timing variation due to disk I/O, the benchmark programs read all XML files into in-memory buffers prior to the test runs.

Note: Interested readers can download the benchmark program from Resources.

Parsing throughput comparisons

Ovaj odjeljak prikazuje izvedbu raščlanjivanja XML-a i u kašnjenju i u protoku. Primijetite da, iako su VTD-XML i DOM izravno usporedivi, nije pošteno uspoređivati ​​VTD-XML sa SAX-om ili Pull-om jer oni ne grade nikakvu hijerarhijsku strukturu u memoriji. Dakle, izvedba za SAX i Pull služi samo kao dodatna referentna točka.

Propusnost

Usporedbe latencija

Tablica 1. Male datoteke

Naziv / veličina datoteke VTD-XML (ms) Ponovna upotreba VTD-XML međuspremnika (ms) SAX (ms) DOM (ms) DOM odgođen (ms) Piccolo (ms) Povucite (ms)
soap2.xml (1727 bajtova) 0,0446 0,0346 0,0782 0,1122 0,16225 0,092 0,066
nav_48_0.xml (4608 bajtova) 0,1054 0,0928 0,266 0,37 0,385 0,2784 0,1742
cd_catalog.xml (5035 bajtova) 0,118 0,108 0,19 0,348 0,4 0,2 0,214
nav_63_0.xml (6848 bajtova) 0,149 0,135 0,354 0,513 0,557 0,484 0,242
nav_78_0.xml (6920 bajtova) 0,153 0,142 0,3704 0,588 0,52 0,42 0,29

Tablica 2. Srednje XML datoteke