Προγραμματισμός

Απλοποιήστε την επεξεργασία XML με VTD-XML

Εικόνα 3. Μεγάλα αρχεία XML. Κάντε κλικ στη μικρογραφία για προβολή εικόνας πλήρους μεγέθους.

Οκτώ χρόνια από την ίδρυσή της, η XML έχει ήδη ξεκινήσει ως ανοιχτή, ημι-δομημένη μορφή δεδομένων για την αποθήκευση δεδομένων καθώς και την ανταλλαγή δεδομένων μέσω του Διαδικτύου. Λόγω της απλότητας και της ανθρώπινης αναγνωσιμότητάς της, η XML έβλεπε την άνοδο της δημοτικότητάς της στους προγραμματιστές εφαρμογών και έχει καταστεί απαραίτητο μέρος της αρχιτεκτονικής των επιχειρήσεων.

Παρόλο που είναι δύσκολο να απαριθμηθεί ο αριθμός των τρόπων με τους οποίους χρησιμοποιείται η XML, μπορεί κανείς να είναι σίγουρος για ένα πράγμα: το XML πρέπει να αναλυθεί πριν να γίνει οτιδήποτε άλλο. Στην πραγματικότητα, η επιλογή του σωστού αναλυτή είναι συχνά μία από τις πρώτες αποφάσεις που πρέπει να αντιμετωπίσουν οι προγραμματιστές επιχειρήσεων στα έργα τους. Και ξανά και ξανά, αυτή η απόφαση έρχεται στα δύο δημοφιλή μοντέλα επεξεργασίας XML: το Document Object Model (DOM) και το Simple API for XML (SAX).

Με την πρώτη ματιά, τα αντίστοιχα πλεονεκτήματα και αδυναμίες των DOM και SAX φαίνονται συμπληρωματικά: Το DOM δημιουργεί γραφήματα αντικειμένων στη μνήμη. Το SAX βασίζεται σε εκδηλώσεις και δεν αποθηκεύει τίποτα στη μνήμη. Επομένως, εάν το μέγεθος του εγγράφου είναι μικρό και το μοτίβο πρόσβασης δεδομένων, πολύπλοκο, το DOM είναι ο τρόπος να πάτε Διαφορετικά, χρησιμοποιήστε το SAX.

Ωστόσο, η αλήθεια δεν είναι ποτέ τόσο απλοϊκή. Τις περισσότερες φορές, οι προγραμματιστές δεν θέλουν να χρησιμοποιήσουν το SAX λόγω της πολυπλοκότητάς του, αλλά εξακολουθούν να το κάνουν επειδή δεν υπάρχει άλλη βιώσιμη επιλογή. Διαφορετικά, εάν το μέγεθος αρχείου XML είναι λίγο λίγο μεγαλύτερο από μερικές εκατοντάδες kilobyte, η επιβάρυνση της μνήμης DOM και η απόδοση απόδοσης γίνονται ένα δύσκολο εμπόδιο για τους προγραμματιστές εφαρμογών, εμποδίζοντας τους να εκπληρώσουν τους ελάχιστους στόχους απόδοσης των έργων τους.

Αλλά είναι το SAX πραγματικά πολύ καλύτερο; Η διαφημιζόμενη απόδοση ανάλυσης του SAX - συνήθως πολλές φορές πιο γρήγορη από το DOM - είναι στην πραγματικότητα συχνά εξαπατά. Αποδεικνύεται ότι η αμήχανη, μόνο προς τα εμπρός φύση της ανάλυσης SAX όχι μόνο απαιτεί επιπλέον προσπάθεια υλοποίησης, αλλά επίσης επιβάλλει κυρώσεις απόδοσης όταν η δομή του εγγράφου γίνεται ελαφρώς περίπλοκη. Εάν οι προγραμματιστές επιλέξουν να μην σαρώσουν το έγγραφο πολλές φορές, θα πρέπει να αποθηκεύσουν το έγγραφο ή να δημιουργήσουν προσαρμοσμένα μοντέλα αντικειμένων.

Όπως και να έχει, η απόδοση υποφέρει, όπως φαίνεται από τον Apache Axis. Στη σελίδα Συχνές ερωτήσεις, η Axis ισχυρίζεται ότι χρησιμοποιεί εσωτερικά το SAX για να δημιουργήσει μια υλοποίηση υψηλότερης απόδοσης, αλλά εξακολουθεί να κατασκευάζει το δικό του μοντέλο αντικειμένου που μοιάζει με DOM, με αποτέλεσμα αμελητέες βελτιώσεις απόδοσης σε σύγκριση με τον προκάτοχό του (Apache SOAP). Επιπλέον, το SAX δεν λειτουργεί καλά με το XPath και γενικά δεν μπορεί να οδηγήσει την επεξεργασία XSLT (Extensible Stylesheet Language Transformation). Έτσι, το SAX αναλύει τα πραγματικά προβλήματα της επεξεργασίας XML.

Αναζητώντας μια ευκολότερη στη χρήση εναλλακτική λύση για το SAX, ένας αυξανόμενος αριθμός προγραμματιστών έχει στραφεί στο StAX (Streaming API για XML). Σε σύγκριση με το SAX, οι αναλυτές StAX τραβούν διακριτικά από αρχεία XML αντί να χρησιμοποιούν επιστροφή κλήσεων. Ενώ βελτιώνουν αισθητά τη χρηστικότητα, τα βασικά ζητήματα παραμένουν - το στυλ ανάλυσης του StAX μόνο προς τα εμπρός απαιτεί ακόμα κουραστική προσπάθεια εφαρμογής και, μαζί με αυτό, κρυφό κόστος απόδοσης

Η κατώτατη γραμμή: Για οποιοδήποτε μοντέλο επεξεργασίας XML είναι γενικά χρήσιμο, πρέπει να παρουσιάζει την ιεραρχική δομή της XML και τίποτα λιγότερο. Ο λόγος είναι επειδή η XML έχει σχεδιαστεί για τη μεταφορά σύνθετων δεδομένων μέσω του Διαδικτύου και η μεταφορά των δομικών πληροφοριών είναι εγγενές μέρος αυτού που κάνει η XML.

Το VTD-XML αλλάζει το παιχνίδι

Ας υποθέσουμε ότι ξεκινήσαμε την επεξεργασία XML από το μηδέν για να ξεπεράσουμε τα προαναφερθέντα ζητήματα με τα DOM και SAX. Το νέο μοντέλο πιθανόν να έχει τις ακόλουθες ιδιότητες:

  • Τυχαία πρόσβαση με δυνατότητα: Το μοντέλο επεξεργασίας θα πρέπει να επιτρέπει στον προγραμματιστή να πλοηγείται σε κάποιο είδος ιεραρχικής δομής είτε χειροκίνητα είτε, καλύτερα, χρησιμοποιώντας το XPath.
  • Υψηλή απόδοση: Η απόδοση θα πρέπει να είναι σημαντικά καλύτερη από τις DOM και SAX. Και η παράσταση πρέπει να είναι «ειλικρινής», που σημαίνει ότι η μέτρηση πρέπει να περιλαμβάνει το χρόνο που αφιερώνεται στην οικοδόμηση της ιεραρχικής δομής.
  • Χαμηλή χρήση μνήμης: Για να καταστήσει το μοντέλο επεξεργασίας εφαρμόσιμο σε ένα ευρύ φάσμα σεναρίων και μεγεθών αρχείων, πρέπει να παρουσιάζει την πλήρη δομή του XML με ελάχιστο όγκο χρήσης μνήμης.

Σχεδιασμένο για την επίτευξη αυτών των στόχων, το VTD-XML είναι το μοντέλο επεξεργασίας XML ανοιχτού κώδικα επόμενης γενιάς που φέρνει θεμελιώδεις και παντού βελτιώσεις σε σχέση με τα DOM και SAX. Μία βασική βελτιστοποίηση του VTD-XML είναι η μη εκχυλιστική κωδικοποίηση. Εσωτερικά, το VTD-XML διατηρεί στη μνήμη το άθικτο και μη κωδικοποιημένο μήνυμα XML και αντιπροσωπεύει μάρκες αποκλειστικά με βάση μια προδιαγραφή δυαδικής κωδικοποίησης που ονομάζεται Βατύχημα Τεντάξει ρεεκδότης. Η εγγραφή VTD είναι ένας ακέραιος αριθμός 64-bit που κωδικοποιεί το μήκος του διακριτικού, την αρχική μετατόπιση, τον τύπο και το βάθος ένθεσης ενός διακριτικού σε XML.

Εδώ είναι λίγο το ιστορικό του VTD-XML σε περίπτωση που σας ενδιαφέρει: Η βασική ιδέα σχεδιάστηκε ως τρόπος μεταφοράς XML σε ειδικό υλικό, με τη μορφή FPGA ή ASIC, για να επιτρέψετε στους διακόπτες δικτύου και τους δρομολογητές να επεξεργάζονται XML περιεχόμενο σε πολύ υψηλές ταχύτητες. Αργότερα, η ομάδα έργου VTD-XML αποφάσισε να ανοίξει το VTD-XML πηγής και η αρχική έκδοση - της έκδοσης 0,5 και υλοποιήθηκε στην Java - πραγματοποιήθηκε τον Μάιο του 2004. Από την κυκλοφορία αυτή, το VTD-XML έχει υποστεί αρκετούς γύρους βελτιώσεων και ωριμάζει πολύ. Στην έκδοση 0.8, κυκλοφόρησε η έκδοση C του VTD-XML μαζί με την έκδοση Java. Η ενσωματωμένη υποστήριξη XPath κυκλοφόρησε στην έκδοση 1.0 και κυκλοφόρησε τον Οκτώβριο του 2005. Η τελευταία έκδοση, έκδοση 1.5, διαθέτει έναν επανασχεδιασμένο κινητήρα ανάλυσης που είναι πιο αρθρωτός και υψηλότερης απόδοσης.

Επίσης κυκλοφόρησε σε αυτήν την έκδοση είναι ένα χαρακτηριστικό που ονομάζεται buffer reuse. Η βασική ιδέα είναι ότι όταν μια εφαρμογή XML που βρίσκεται πίσω από μια σύνδεση δικτύου πρέπει να επεξεργάζεται επανειλημμένα πολλά εισερχόμενα έγγραφα XML, η εφαρμογή μπορεί στην πραγματικότητα να επαναχρησιμοποιήσει τα buffer μνήμης που εκχωρήθηκαν κατά την πρώτη εκτέλεση της επεξεργασίας. Με άλλα λόγια, εκχωρήστε buffer μία φορά και χρησιμοποιήστε τα πολλές, πολλές φορές. Ειδικά για το VTD-XML, αυτή η δυνατότητα επιτρέπει την πλήρη εξάλειψη τόσο της δημιουργίας αντικειμένων όσο και του κόστους συλλογής απορριμμάτων (50-80 τοις εκατό των γενικών εξόδων σε DOM και SAX) από την επεξεργασία XML. Ο ιστότοπος του έργου περιέχει τις τελευταίες λήψεις λογισμικού και μια λεπτομερή τεχνική περιγραφή του VTD-XML.

Ένα γρήγορο παράδειγμα

Για να δώσει μια αίσθηση του στυλ προγραμματισμού του VTD-XML, αυτό το άρθρο συγκρίνει πρώτα τον κώδικα χρησιμοποιώντας τόσο το VTD-XML όσο και το DOM για την ανάλυση και πλοήγηση σε ένα απλό αρχείο XML με το όνομα test.xml, του οποίου το περιεχόμενο κειμένου εμφανίζεται παρακάτω:

  Χλοοκοπτικό 1 148.95 

Η έκδοση VTD-XML μοιάζει με αυτήν:

εισαγωγή com.ximpleware. *; εισαγωγή com.ximpleware.parser. *; εισαγωγή java.io. *;

δημόσια τάξη use_vtd {public static void main (String [] args) {try {File f = new File ("test.xml"); FileInputStream fis = νέο FileInputStream (f); byte [] ba = νέο byte [(int) f.length ()]; fis.read (βα); VTDGen vg = νέο VTDGen (); vg.setDoc (βα); vg.parse (false); VTDNav vn = vg.getNav (); if (vn.matchElement ("pembelianOrder")) {System.out.println ("orderDate ==>" + vn.toString (vn.getAttrVal ("orderDate"))); εάν (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 ())); } ενώ (vn.toElement (VTDNav.NEXT_SIBLING)); }}}} catch (Εξαίρεση e) {System.out.println ("Η εξαίρεση προέκυψε ==>" + e); }}}

Η έκδοση DOM της ίδιας εφαρμογής εμφανίζεται παρακάτω:

εισαγωγή java.io. *; εισαγωγή org.w3c.dom. *; εισαγωγή org.w3c. *; εισαγωγή javax.xml.parsers. *; εισαγωγή javax.xml.parsers.DocumentBuilder; εισαγωγή javax.xml.parsers.DocumentBuilderFactory; εισαγωγή javax.xml.parsers.FactoryConfigurationError; εισαγωγή javax.xml.parsers.ParserConfigurationException; εισαγωγή org.w3c.dom. *; εισαγωγή org.xml.sax.SAXException;

δημόσια τάξη use_dom {public static void main (String [] args) {try {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance (); DocumentBuilder parser = factory.newDocumentBuilder (); Έγγραφο d = parser.parse ("test.xml"); Στοιχείο root = d.getDocumentElement (); if (root.getNodeName (). membandingkanTo ("pembelianOrder") == 0) {System.out.println ("orderDate ==>" + root.getAttribute ("orderDate"));

Κόμβος n = root.getFirstChild (); if (n! = null) {do {if (n.getNodeType () == Node.ELEMENT_NODE && n.getNodeName (). membandingkanTo ("item") == 0) {Node n2 = n.getFirstChild (); if (n2! = null) {do {if (n2.getNodeType () == Node.ELEMENT_NODE) ​​{System.out.println (n2.getNodeName () + "==>" + n2.getFirstChild (). getNodeValue ( )) }} ενώ ((n2 = n2.getNextSibling ())! = null); }}} ενώ ((n = n.getNextSibling ())! = null); }}} catch (Εξαίρεση e) {System.out.println ("εξαίρεση συνέβη ==>" + e); }}}

Όπως φαίνεται στα παραπάνω παραδείγματα κώδικα, το VTD-XML πλοηγεί την ιεραρχία XML χρησιμοποιώντας ένα API που βασίζεται σε δρομέα. Αντίθετα, το DOM API πλοηγεί την ιεραρχία ζητώντας αναφορές αντικειμένων. Επισκεφθείτε τον ιστότοπο του έργου VTD-XML για περισσότερα τεχνικά υλικά και παραδείγματα κώδικα που εξηγούν το VTD-XML σε βάθος.

Συγκριτική αξιολόγηση VTD-XML

Στη συνέχεια, ας συγκρίνουμε την απόδοση και τη χρήση μνήμης του VTD-XML με μερικούς δημοφιλείς αναλυτές XML. Πρέπει να σημειωθεί ότι τα περισσότερα άρθρα που περιέχουν αριθμούς αναφοράς, όπως "XML Documents on the Run" του Dennis Sosnoski (JavaWorld, Απρίλιος 2002), είναι από αρκετά χρόνια πριν. Έκτοτε, καλύτερο και γρηγορότερο υλικό ακολουθεί τον Νόμο του Μουρ και γίνεται φθηνότερο από ποτέ. Ταυτόχρονα, η ανάλυση XML και η εικονική μηχανή Java δεν έχουν σταματήσει - έχουν δει βελτιώσεις σε πολλούς βασικούς τομείς.

Ρύθμιση δοκιμής

Η δοκιμαστική πλατφόρμα είναι ένας φορητός υπολογιστής Sony VAIO εξοπλισμένος με επεξεργαστή Pentium M 1,7 GHz (ενσωματωμένη μνήμη L2 cache 2 MB) και μνήμη RAM 512 MB DDR2. Το μπροστινό λεωφορείο έχει ροπή στα 400 MHz. Το λειτουργικό σύστημα είναι Windows XP Professional Edition με service pack 2. Το JVM είναι έκδοση 1.5.0_06.

Το σημείο αναφοράς δοκιμάζει τις τελευταίες εκδόσεις των ακόλουθων αναλυτών XML:

  • Xerces DOM 2.7.1, με και χωρίς αναβαλλόμενη επέκταση κόμβου
  • Xerces SAX 2.7.1
  • Piccolo SAX 1.04
  • XPP3 1.1.3.4.O
  • VTD-XML 1.5, με και χωρίς επαναχρησιμοποίηση buffer

Επέλεξα μια μεγάλη συλλογή εγγράφων XML διαφόρων μεγεθών και δομικών περιπλοκών για τη δοκιμή. Ανάλογα με το μέγεθος του αρχείου, τα δοκιμαστικά έγγραφα ομαδοποιούνται σε τρεις κατηγορίες. Τα μικρά αρχεία έχουν μέγεθος μικρότερο από 10 KB. Τα αρχεία μεσαίου μεγέθους κυμαίνονται μεταξύ 10 KB και 1 MB. Τα αρχεία μεγαλύτερα από 1 MB θεωρούνται μεγάλα.

Ο διακομιστής JVM χρησιμοποιήθηκε για όλες τις μετρήσεις απόδοσης για να επιτευχθεί η μέγιστη απόδοση. Σε αυτές τις δοκιμές, τα προγράμματα αναφοράς συγκρίθηκαν για πρώτη φορά μέσω της ρουτίνας ανάλυσης ή πλοήγησης πολλές φορές, έτσι ώστε το JVM να εκτελεί τη δυναμική, just-in-time βελτιστοποίηση του κώδικα byte, πριν από τον μέσο όρο της απόδοσης των επακόλουθων επαναλήψεων ως τελικά αποτελέσματα. Για τη μείωση της χρονικής διακύμανσης λόγω του δίσκου I / O, τα προγράμματα αναφοράς διαβάζουν όλα τα αρχεία XML σε buffer μνήμης πριν από τις δοκιμές.

Σημείωση: Οι ενδιαφερόμενοι αναγνώστες μπορούν να κατεβάσουν το πρόγραμμα αναφοράς από τους πόρους.

Ανάλυση συγκρίσεων απόδοσης

Αυτή η ενότητα παρουσιάζει την απόδοση ανάλυσης XML τόσο σε καθυστέρηση όσο και σε απόδοση. Σημειώστε ότι ενώ τα VTD-XML και DOM είναι άμεσα συγκρίσιμα, δεν είναι δίκαιο να συγκρίνετε το VTD-XML με το SAX ή το Pull επειδή δεν δημιουργούν ιεραρχική δομή στη μνήμη. Επομένως, η απόδοση για SAX και Pull χρησιμεύει μόνο ως πρόσθετο σημείο αναφοράς.

Διακίνηση

Συγκρίσεις καθυστέρησης

Πίνακας 1. Μικρά αρχεία

Όνομα / μέγεθος αρχείουVTD-XML (ms)Επαναχρησιμοποίηση buffer VTD-XML (ms)SAX (ms)DOM (ms)Αναβολή DOM (ms)Piccolo (ms)Τραβήξτε (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 byte)0.1490.1350.3540.5130.5570.4840.242
nav_78_0.xml (6920 byte)0.1530.1420.37040.5880.520.420.29

Πίνακας 2. Μέσα αρχεία XML