Sederhanakan pemrosesan XML dengan VTD-XML

Gambar 3. File XML besar. Klik pada thumbnail untuk melihat gambar berukuran penuh.

Delapan tahun sejak dimulainya, XML telah diluncurkan sebagai format data semi-terstruktur terbuka untuk menyimpan data serta bertukar data melalui Web. Karena kesederhanaan dan keterbacaan manusia, XML telah melihat popularitasnya meroket di kalangan pengembang aplikasi dan telah menjadi bagian tak terpisahkan dari arsitektur perusahaan.

Meskipun sulit untuk menghitung jumlah cara penggunaan XML, satu hal yang pasti tentang satu hal: XML harus diurai sebelum hal lain dapat dilakukan. Faktanya, memilih parser yang tepat sering kali merupakan salah satu keputusan pertama yang harus ditangani oleh pengembang perusahaan dalam proyek mereka. Dan lagi dan lagi, keputusan itu turun ke dua model pemrosesan XML yang populer: Model Objek Dokumen (DOM) dan API Sederhana untuk XML (SAX).

Sekilas, kekuatan dan kelemahan masing-masing DOM dan SAX tampak saling melengkapi: DOM membuat grafik objek dalam memori; SAX berbasis peristiwa dan tidak menyimpan apa pun dalam memori. Jadi, jika ukuran dokumen kecil dan pola akses datanya rumit, DOM adalah cara yang tepat; jika tidak, gunakan SAX.

Namun, kebenaran tidak pernah sesederhana itu. Lebih sering daripada tidak, pengembang tidak mau menggunakan SAX karena kerumitannya, namun tetap melakukannya karena tidak ada pilihan lain yang tersedia. Sebaliknya, jika ukuran file XML hanya sedikit lebih besar dari beberapa ratus kilobyte, overhead memori DOM dan hambatan kinerja menjadi penghalang yang sulit bagi pengembang aplikasi, mencegah mereka memenuhi tujuan kinerja minimum proyek mereka.

Tapi apakah SAX benar-benar jauh lebih baik? Performa penguraian SAX yang diiklankan — biasanya beberapa kali lebih cepat daripada DOM — sebenarnya sering menipu. Ternyata sifat penguraian SAX yang canggung dan hanya maju tidak hanya membutuhkan upaya implementasi ekstra, tetapi juga menimbulkan penalti kinerja ketika struktur dokumen menjadi hanya sedikit kompleks. Jika pengembang memilih untuk tidak memindai dokumen beberapa kali, mereka harus menyangga dokumen atau membangun model objek kustom.

Either way, kinerja menderita, seperti yang dicontohkan oleh Apache Axis. Di halaman FAQ-nya, Axis mengklaim menggunakan SAX secara internal untuk membuat implementasi berperforma lebih tinggi, namun Axis masih membangun model objeknya sendiri yang mirip DOM, menghasilkan peningkatan performa yang dapat diabaikan jika dibandingkan dengan pendahulunya (Apache SOAP). Selain itu, SAX tidak bekerja dengan baik dengan XPath, dan secara umum tidak dapat mendorong pemrosesan XSLT (Extensible Stylesheet Language Transformation). Jadi SAX mem-parsing mengatasi masalah sebenarnya dari pemrosesan XML.

Mencari alternatif yang lebih mudah digunakan untuk SAX, semakin banyak pengembang telah beralih ke StAX (Streaming API untuk XML). Dibandingkan dengan SAX, parser StAX menarik token dari file XML alih-alih menggunakan panggilan balik. Meskipun mereka secara nyata meningkatkan kegunaan, masalah mendasar tetap ada — gaya parsing hanya-maju StAX masih membutuhkan upaya implementasi yang membosankan dan, bersamaan dengan itu, biaya kinerja tersembunyi.

Intinya: Agar model pemrosesan XML apa pun berguna secara luas, model tersebut harus menyajikan struktur hierarki XML dan tidak kurang dari itu. Alasannya adalah karena XML dirancang untuk memindahkan data kompleks melalui Web, dan menyampaikan informasi struktural adalah bagian inheren dari apa yang dilakukan XML.

VTD-XML mengubah permainan

Misalkan kita memulai pemrosesan XML dari awal untuk mengatasi masalah yang disebutkan di atas dengan DOM dan SAX. Model baru mungkin harus memiliki properti berikut:

  • Dapat mengakses acak: Model pemrosesan harus memungkinkan pengembang untuk menavigasi semacam struktur hierarki baik secara manual atau, lebih baik, dengan menggunakan XPath.
  • Performa tinggi: Performa harus jauh lebih baik daripada DOM dan SAX. Dan kinerjanya harus "jujur", yang berarti pengukuran harus mencakup waktu yang dihabiskan untuk membangun struktur hierarki.
  • Penggunaan memori rendah: Untuk membuat model pemrosesan dapat diterapkan pada berbagai skenario dan ukuran file, model harus menampilkan struktur XML lengkap dengan jumlah penggunaan memori minimum.

Didesain untuk memenuhi tujuan tersebut, VTD-XML adalah model pemrosesan XML open source generasi berikutnya yang menghadirkan peningkatan mendasar dan menyeluruh atas DOM dan SAX. Salah satu pengoptimalan utama VTD-XML adalah tokenisasi non-ekstraktif. Secara internal, VTD-XML mempertahankan dalam memori utuh dan undecoded pesan XML, dan mewakili token secara eksklusif berdasarkan spesifikasi pengkodean biner disebut V irtual T Oken D escriptor. Data VTD adalah bilangan bulat 64-bit yang menyandikan panjang token, offset awal, jenis, dan kedalaman penyarangan token dalam XML.

Berikut ini sedikit sejarah VTD-XML jika Anda tertarik: Konsep dasar disusun sebagai cara untuk mem-port pemrosesan XML pada perangkat keras khusus, dalam bentuk FPGA atau ASIC, untuk mengaktifkan sakelar jaringan dan router untuk memproses XML konten dengan kecepatan sangat tinggi. Kemudian, tim proyek VTD-XML memutuskan untuk membuka VTD-XML sumber terbuka, dan rilis awal — versi 0.5 dan diimplementasikan di Java — berlangsung pada Mei 2004. Sejak rilis itu, VTD-XML telah mengalami beberapa tahap perbaikan dan matang. sangat. Dalam versi 0.8, versi C dari VTD-XML dirilis bersama dengan versi Java. Dukungan XPath internal diperkenalkan pada versi 1.0 dan dirilis pada Oktober 2005. Rilis terbaru, versi 1.5, menampilkan mesin parsing yang ditulis ulang yang lebih modular dan berkinerja lebih tinggi.

Juga diperkenalkan dalam rilis ini adalah fitur yang disebut penggunaan kembali buffer. Ide dasarnya adalah ketika aplikasi XML yang berada di belakang koneksi jaringan perlu memproses banyak dokumen XML yang masuk secara berulang, aplikasi tersebut sebenarnya dapat menggunakan kembali buffer memori yang dialokasikan selama proses pertama dijalankan. Dengan kata lain, alokasikan buffer sekali dan gunakan berkali-kali. Khusus untuk VTD-XML, fitur ini memungkinkan penghapusan total biaya pembuatan objek dan pengumpulan sampah (50-80 persen dari overhead di DOM dan SAX) dari pemrosesan XML. Situs web proyek berisi unduhan perangkat lunak terbaru dan deskripsi teknis mendalam tentang VTD-XML.

Contoh cepat

Untuk memberikan kesan gaya pemrograman VTD-XML, artikel ini pertama-tama membandingkan kode menggunakan VTD-XML dan DOM untuk mengurai dan menavigasi file XML sederhana bernama test.xml, yang konten teksnya ditampilkan di bawah ini:

  Lawnmower 1 148.95  

Versi VTD-XML terlihat seperti ini:

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); } } }

Versi DOM dari aplikasi yang sama ditunjukkan di bawah ini:

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); } } }

Seperti yang diilustrasikan dalam contoh kode di atas, VTD-XML menavigasi hierarki XML menggunakan API berbasis kursor. Sebaliknya, DOM API menavigasi hierarki dengan meminta referensi objek. Silakan kunjungi Situs web proyek VTD-XML untuk materi lebih teknis dan contoh kode yang menjelaskan VTD-XML secara mendalam.

Pembandingan VTD-XML

Selanjutnya, mari kita bandingkan kinerja VTD-XML dan penggunaan memori dengan beberapa parser XML yang populer. Perlu dicatat bahwa sebagian besar artikel yang berisi nomor patokan, seperti "XML Documents on the Run" oleh Dennis Sosnoski ( JavaWorld , April 2002), berasal dari beberapa tahun yang lalu. Sejak itu, perangkat keras yang lebih baik dan lebih cepat mengikuti Hukum Moore dan menjadi lebih murah dari sebelumnya. Pada saat yang sama, penguraian XML dan mesin virtual Java masih belum berhenti — mereka telah melihat peningkatan di banyak area utama.

Uji penyiapan

Platform pengujiannya adalah laptop Sony VAIO yang dilengkapi dengan prosesor Pentium M 1,7 GHz (2 MB L2 cache terintegrasi) dan RAM DDR2 512 MB. Bus depan memiliki clock 400 MHz. OS adalah Windows XP Professional Edition dengan paket layanan 2. JVM adalah versi 1.5.0_06.

Tolok ukur menguji versi terbaru pengurai XML berikut:

  • Xerces DOM 2.7.1, dengan dan tanpa perluasan node yang ditangguhkan
  • Xerces SAX 2.7.1
  • Piccolo SAX 1.04
  • XPP3 1.1.3.4.O
  • VTD-XML 1.5, dengan dan tanpa penggunaan ulang buffer

Saya memilih banyak koleksi dokumen XML dengan berbagai ukuran dan kompleksitas struktural untuk pengujian. Bergantung pada ukuran file, dokumen pengujian dikelompokkan ke dalam tiga kategori. File kecil berukuran kurang dari 10 KB. File berukuran sedang antara 10 KB dan 1 MB. File yang lebih besar dari 1 MB dianggap besar.

Server JVM digunakan untuk semua pengukuran kinerja untuk mendapatkan kinerja puncak. Dalam pengujian tersebut, program benchmark pertama kali mengulang melalui penguraian atau navigasi rutin berkali-kali sehingga JVM melakukan optimasi kode byte dinamis dan tepat waktu, sebelum rata-rata kinerja iterasi berikutnya sebagai hasil akhir. Untuk mengurangi variasi waktu karena disk I / O, program benchmark membaca semua file XML ke dalam buffer dalam memori sebelum pengujian dijalankan.

Catatan: Pembaca yang tertarik dapat mengunduh program benchmark dari Resources.

Mengurai perbandingan throughput

Bagian ini menyajikan kinerja penguraian XML dalam latensi dan throughput. Perhatikan bahwa meskipun VTD-XML dan DOM dapat dibandingkan secara langsung, tidaklah adil untuk membandingkan VTD-XML dengan SAX atau Pull karena keduanya tidak membangun struktur hierarki apa pun dalam memori. Jadi performa untuk SAX dan Pull hanya berfungsi sebagai titik referensi tambahan.

Throughput

Perbandingan latensi

Tabel 1. File kecil

Nama / ukuran file VTD-XML (md) Penggunaan kembali buffer VTD-XML (md) SAX (md) DOM (md) DOM ditangguhkan (md) Piccolo (md) Tarik (md)
soap2.xml (1727 byte) 0,0446 0,0346 0,0782 0.1122 0.16225 0,092 0,066
nav_48_0.xml (4608 byte) 0.1054 0,0928 0,266 0.37 0,385 0.2784 0.1742
cd_catalog.xml (5035 byte) 0.118 0.108 0.19 0,348 0.4 0.2 0.214
nav_63_0.xml (6848 byte) 0.149 0.135 0,354 0,513 0,557 0.484 0.242
nav_78_0.xml (6920 byte) 0.153 0.142 0,3704 0,588 0,52 0.42 0.29

Tabel 2. File XML sedang