Programování

Zjednodušte zpracování XML pomocí VTD-XML

Obrázek 3. Velké soubory XML. Kliknutím na miniaturu zobrazíte obrázek v plné velikosti.

Osm let od svého založení se XML již stalo otevřeným, polostrukturovaným datovým formátem pro ukládání dat a jejich výměnu přes web. Díky své jednoduchosti a čitelnosti pro člověka zaznamenala XML mezi vývojáři aplikací svoji popularitu a stala se nepostradatelnou součástí podnikové architektury.

I když je obtížné vyjmenovat počet způsobů použití XML, lze si být jisti jednou věcí: XML musí být analyzován, než bude možné provést cokoli jiného. Ve skutečnosti je výběr správného analyzátoru často jedním z prvních rozhodnutí, která musí podnikoví vývojáři ve svých projektech řešit. Toto rozhodnutí znovu a znovu přichází ke dvěma populárním modelům zpracování XML: Document Object Model (DOM) a Simple API for XML (SAX).

Na první pohled se příslušné silné a slabé stránky DOM a SAX zdají doplňkové: DOM vytváří grafy objektů v paměti; SAX je založen na událostech a neukládá nic do paměti. Pokud je tedy velikost dokumentu malá a vzor přístupu k datům složitý, DOM je správná cesta; jinak použijte SAX.

Pravda však nikdy není tak zjednodušující. Vývojáři častěji nejsou ochotni používat SAX kvůli jeho složitosti, přesto to však dělají, protože není k dispozici žádná jiná životaschopná volba. V opačném případě, pokud je velikost souboru XML jen o něco větší než několik stovek kilobajtů, režie paměti DOM a přetažení výkonu se stanou pro vývojáře aplikací těžkou překážkou, která jim brání v plnění cílů minimálního výkonu jejich projektů.

Je ale SAX opravdu o tolik lepší? Inzerovaný výkon analýzy SAX - obvykle několikanásobně rychlejší než DOM - ve skutečnosti často klame. Ukazuje se, že nepříjemná, dopředná povaha analýzy SAX vyžaduje nejen další úsilí při implementaci, ale také způsobí penalizace výkonu, když se struktura dokumentu stane jen mírně složitou. Pokud se vývojáři rozhodnou dokument několikrát neskenovat, budou muset dokument uložit do vyrovnávací paměti nebo vytvořit vlastní modely objektů.

Ať tak či onak, výkon trpí, jak dokládá Apache Axis. Na své stránce s často kladenými dotazy společnost Axis tvrdí, že interně používá SAX k vytvoření výkonnější implementace, přesto si stále staví svůj vlastní objektový model, který je zcela podobný modelu DOM, což má za následek zanedbatelné vylepšení výkonu ve srovnání s jeho předchůdcem (Apache SOAP). Kromě toho SAX nefunguje dobře s XPath a obecně nemůže řídit zpracování XSLT (Extensible Stylesheet Language Transformation). Analýza SAX tedy skrývá skutečné problémy zpracování XML.

Hledajíc jednodušší alternativu k SAXu, rostoucí počet vývojářů se obrátil na StAX (Streaming API pro XML). Ve srovnání s SAX analyzátory StAX získávají tokeny ze souborů XML namísto použití zpětných volání. I když znatelně zlepšují použitelnost, základní problémy přetrvávají - styl syntaktické analýzy StAX stále vyžaduje zdlouhavé implementační úsilí a spolu s ním i skryté náklady na výkon.

Závěr: Aby byl jakýkoli model zpracování XML široce užitečný, musí představovat hierarchickou strukturu XML a nic méně. Důvodem je to, že XML je navržen tak, aby přesouval složitá data po webu, a přenos strukturálních informací je nedílnou součástí toho, co XML dělá.

VTD-XML mění hru

Předpokládejme, že jsme měli zahájit zpracování XML od nuly, abychom překonali výše uvedené problémy s DOM a SAX. Nový model by pravděpodobně měl mít následující vlastnosti:

  • Možnost náhodného přístupu: Model zpracování by měl vývojáři umožnit navigovat v nějaké hierarchické struktuře buď ručně, nebo lépe pomocí XPath.
  • Vysoký výkon: Výkon by měl být podstatně lepší než DOM a SAX. A výkon by měl být „upřímný“, což znamená, že měření musí zahrnovat čas strávený budováním hierarchické struktury.
  • Nízké využití paměti: Aby byl model zpracování použitelný pro širokou škálu scénářů a velikostí souborů, musí představovat úplnou strukturu XML s minimálním využitím paměti.

Pro splnění těchto cílů je VTD-XML navržen jako otevřený zdrojový model zpracování XML XML, který přináší zásadní a všestranná vylepšení oproti DOM a SAX. Jednou z klíčových optimalizací VTD-XML je neextrakční tokenizace. Interně VTD-XML uchovává v paměti neporušenou a nedekódovanou zprávu XML a představuje tokeny výhradně na základě specifikace binárního kódování s názvem PROTIirtual Token Deskriptor. Záznam VTD je 64bitové celé číslo, které kóduje délku tokenu, počáteční offset, typ a hloubku vnoření tokenu v XML.

Tady je trochu historie VTD-XML, pokud vás to zajímá: Základní koncept byl koncipován jako způsob přenosu portů XML na vyhrazeném hardwaru ve formě FPGA nebo ASIC, aby umožnil síťovým přepínačům a routerům zpracovávat XML obsah při velmi vysokých rychlostech. Později se projektový tým VTD-XML rozhodl otevřít zdrojový VTD-XML a počáteční vydání - verze 0.5 a implementované v Javě - proběhlo v květnu 2004. Od tohoto vydání prošel VTD-XML několika vylepšeními a dospěl značně. Ve verzi 0.8 byla vydána verze C VTD-XML spolu s verzí Java. Integrovaná podpora XPath byla představena ve verzi 1.0 a vydána v říjnu 2005. Nejnovější verze, verze 1.5, obsahuje přepsaný modul analýzy, který je více modulární a výkonnější.

V této verzi je také představena funkce zvaná opětovné použití vyrovnávací paměti. Základní myšlenkou je, že když aplikace XML sedící za síťovým připojením potřebuje opakovaně zpracovávat mnoho příchozích dokumentů XML, může aplikace ve skutečnosti znovu použít vyrovnávací paměti přidělené během prvního běhu zpracování. Jinými slovy, přidělte vyrovnávací paměti jednou a použijte je mnohokrát. Tato funkce specifická pro VTD-XML umožňuje úplné vyloučení jak vytváření objektů, tak nákladů na sběr odpadu (50-80 procent režie v DOM a SAX) ze zpracování XML. Web projektu obsahuje nejnovější stahování softwaru a podrobný technický popis VTD-XML.

Rychlý příklad

Abychom získali představu o stylu programování VTD-XML, tento článek nejprve porovnává kód pomocí VTD-XML a DOM k analýze a navigaci v jednoduchém souboru XML s názvem test.xml, jehož textový obsah je uveden níže:

  Sekačka na trávu 1 148,95 

Verze VTD-XML vypadá takto:

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

public class use_vtd {public static void main (String [] args) {try {File f = new File ("test.xml"); FileInputStream fis = nový FileInputStream (f); byte [] ba = nový bajt [(int) f.length ()]; fis.read (ba); VTDGen vg = nový 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 (Výjimka e) {System.out.println ("došlo k výjimce ==>" + e); }}}

Verze DOM stejné aplikace je uvedena níže:

importovat java.io. *; import org.w3c.dom. *; import org.w3c. *; importovat 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 (); Analyzátor DocumentBuilder = factory.newDocumentBuilder (); Dokument d = parser.parse ("test.xml"); Kořen prvku = d.getDocumentElement (); if (root.getNodeName (). compareTo ("purchaseOrder") == 0) {System.out.println ("orderDate ==>" + root.getAttribute ("orderDate"));

Uzel 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 (Výjimka e) {System.out.println ("došlo k výjimce ==>" + e); }}}

Jak je znázorněno v příkladech kódu výše, VTD-XML naviguje hierarchii XML pomocí rozhraní API založeného na kurzoru. Naproti tomu rozhraní API DOM naviguje v hierarchii požadováním odkazů na objekty. Navštivte webové stránky projektu VTD-XML, kde najdete další technické materiály a příklady kódů, které velmi podrobně vysvětlují VTD-XML.

Srovnávání VTD-XML

Dále porovnejme výkon a využití paměti VTD-XML s některými populárními analyzátory XML. Je třeba poznamenat, že většina článků obsahujících srovnávací čísla, například „Dokumenty XML za běhu“ od Dennisa Sosnoského (JavaWorld, Duben 2002), jsou z doby před několika lety. Od té doby se lepší a rychlejší hardware řídí Mooreovým zákonem a stává se levnějším než kdy dříve. Současně analýza XML a virtuální stroj Java nestojí na místě - zaznamenali vylepšení v mnoha klíčových oblastech.

Vyzkoušejte nastavení

Testovací platformou je notebook Sony VAIO vybavený procesorem Pentium M 1,7 GHz (2 MB integrované mezipaměti L2) a 512 MB DDR2 RAM. Přední sběrnice je taktována na 400 MHz. OS je Windows XP Professional Edition s aktualizací service pack 2. JVM je verze 1.5.0_06.

Testovací test testuje nejnovější verze následujících analyzátorů XML:

  • Xerces DOM 2.7.1, s nebo bez odloženého rozšíření uzlu
  • Xerces SAX 2.7.1
  • Piccolo SAX 1.04
  • XPP3 1.1.3.4.O
  • VTD-XML 1.5, s opětovným použitím vyrovnávací paměti i bez ní

Pro test jsem vybral velkou sbírku dokumentů XML různých velikostí a strukturálních složitostí. V závislosti na velikosti souboru jsou testovací dokumenty seskupeny do tří kategorií. Malé soubory jsou menší než 10 kB. Soubory střední velikosti se pohybují mezi 10 kB a 1 MB. Soubory větší než 1 MB jsou považovány za velké.

Server JVM byl použit pro všechna měření výkonu k získání špičkového výkonu. V těchto testech testovací programy nejprve opakovaně procházely syntaktickými nebo navigačními rutinami, takže JVM provedl dynamickou optimalizaci bajtového kódu just-in-time, než zprůměroval výkon následných iterací jako konečné výsledky. Aby se snížila variabilita časování v důsledku vstupně-výstupních operací na disku, srovnávací programy načtou všechny soubory XML do vyrovnávacích pamětí před testováním.

Poznámka: Zainteresovaní čtenáři si mohou stáhnout srovnávací program ze zdrojů.

Analýza porovnání propustnosti

Tato část představuje výkon analýzy XML v latenci i propustnosti. Všimněte si, že zatímco VTD-XML a DOM jsou přímo srovnatelné, není spravedlivé porovnávat VTD-XML s SAX nebo Pull, protože v paměti nevytvářejí žádnou hierarchickou strukturu. Takže výkon pro SAX a Pull slouží pouze jako další referenční bod.

Propustnost

Porovnání latence

Tabulka 1. Malé soubory

Název / velikost souboruVTD-XML (ms)Opětovné použití vyrovnávací paměti VTD-XML (ms)SAX (ms)DOM (ms)DOM odloženo (ms)Piccolo (ms)Pull (ms)
soap2.xml (1727 bajtů)0.04460.03460.07820.11220.162250.0920.066
nav_48_0.xml (4608 bajtů)0.10540.09280.2660.370.3850.27840.1742
cd_catalog.xml (5035 bajtů)0.1180.1080.190.3480.40.20.214
nav_63_0.xml (6848 bajtů)0.1490.1350.3540.5130.5570.4840.242
nav_78_0.xml (6920 bajtů)0.1530.1420.37040.5880.520.420.29

Tabulka 2. Střední soubory XML