新興XML處理方法VTD-XML介紹(2)_Xml教程
推薦:怎樣使用XML實(shí)現(xiàn)多渠道接入網(wǎng)站的構(gòu)架一.背景在現(xiàn)在的網(wǎng)站中,接入的渠道是越來(lái)越多了,技術(shù)也是越來(lái)越先進(jìn),WAP, SMS,EMAIL, 傳統(tǒng)的Web, Socket等等,如果連數(shù)據(jù)庫(kù)和LDAP也算接入的話,那在設(shè)計(jì)之中需要擴(kuò)展的空間要做到很好 很好
出路
VTD-XML便是對(duì)以上問(wèn)題的思考后給出的答案,它是一個(gè)non-extractive XML parser,由于它出色的機(jī)制,很好的解決(避免)了上面所提出的各種問(wèn)題,并且還“順便”帶來(lái)了non-extractive的其他好處,像快速的解析與遍歷、XPath的支持、Incremental Update等等。我這里有一組數(shù)據(jù),取自于VTD-XML的官方網(wǎng)站:
VTD-XML的解析速度是SAX(with NULL content handler)的1.5x~2.0x。With NULL content handler的意思就是說(shuō)SAX解析中沒(méi)有插入任何額外的處理邏輯,也就是SAX的最高速度。
VTD-XML的內(nèi)存占用是原XML的1.3x~1.5x(其中1.0x的部分是原XML,0.3x~0.5x是VTD-XML占用的部分),而DOM的內(nèi)存占用則是原XML的5x~10x。舉一個(gè)例子,如果一個(gè)XML的大小是50MB,那么用VTD-XML讀取進(jìn)來(lái)內(nèi)存占用會(huì)在65MB~75MB之間,而DOM的內(nèi)存占用則會(huì)在250M~500MB之間�;谶@個(gè)數(shù)據(jù)用DOM處理大的XML文件幾乎是不可能的選擇。
你可能會(huì)覺(jué)得不可思議,真的可以做出比DOM易用性還好,比SAX還快的XML解析器嗎?別急著下定論,還是來(lái)看看VTD-XML的原理吧!
基本原理
就像大多數(shù)好的產(chǎn)品一樣,VTD-XML的原理并不復(fù)雜,而是很巧妙。為了實(shí)現(xiàn)non-extractive這個(gè)目的,它將原XML文件原封不動(dòng)的以二進(jìn)制的方式讀進(jìn)內(nèi)存,連解碼都不做,然后在這個(gè)byte數(shù)組上解析每個(gè)element的位置并把一些信息記錄下來(lái),之后的遍歷操作便在這些保存下來(lái)的record上進(jìn)行,如果需要提取XML內(nèi)容就利用record中的位置等信息在原始byte數(shù)組上進(jìn)行解碼并返回字符串。這一切看起來(lái)都很簡(jiǎn)單,但是,這個(gè)簡(jiǎn)單的過(guò)程確有多個(gè)性能細(xì)節(jié)在里邊,并且隱藏了若干個(gè)潛在的能力。下面我們首先來(lái)描述一下各個(gè)性能細(xì)節(jié):
為了避免過(guò)多的對(duì)象創(chuàng)建,VTD-XML決定采用原始的數(shù)值類(lèi)型作為record的類(lèi)型,這樣就可以不必用heap。VTD-XML的record機(jī)制就叫做VTD(Virtual Token Descriptor),VTD將性能瓶頸在tokenization階段就解決掉了真的是很巧妙很用心的做法。VTD是一個(gè)64bits長(zhǎng)度的數(shù)值類(lèi)型,記錄了每個(gè)element的起始位置(offset),長(zhǎng)度(length),深度(depth)以及token的類(lèi)型(type)等信息。
注意VTD是固定長(zhǎng)度的(官方?jīng)Q定用64bits),這樣做的目的就是為了提高性能,因?yàn)殚L(zhǎng)度固定,在讀取,查詢(xún)等操作的時(shí)候格外的高效(O(1)),也就是可以用數(shù)組這種高效的結(jié)構(gòu)來(lái)組織VTD大大減少了因?yàn)榇罅渴褂脤?duì)象而產(chǎn)生的性能問(wèn)題。
VTD的超能力(一點(diǎn)都不夸張地說(shuō))就在于它能夠?qū)ML這種樹(shù)形的數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單的變換成對(duì)一個(gè)byte數(shù)組的操作,任何你能想象到的對(duì)于byte數(shù)組的操作都可以應(yīng)用在XML上了。這是因?yàn)樽x取進(jìn)來(lái)的XML是二進(jìn)制的(byte數(shù)組),而VTD則記錄了每個(gè)element的位置等訪問(wèn)用信息,當(dāng)我們找到要操作的VTD的時(shí)候,只要用offset與length等信息就可以對(duì)原始byte數(shù)組進(jìn)行任何操作,或者可以直接對(duì)VTD進(jìn)行操作。舉例來(lái)說(shuō),我想在一個(gè)大XML中找出一個(gè)element并刪除它,那么我只需要找到這個(gè)element的VTD(遍歷方法稍候再講),將這個(gè)VTD從VTD數(shù)組中刪除,然后再利用所有的VTD寫(xiě)出到另一個(gè)byte數(shù)組中就可以了,因?yàn)閯h除的VTD標(biāo)明了要?jiǎng)h除的element的位置,所以在新寫(xiě)入的byte數(shù)組中就不會(huì)出現(xiàn)這段element了,用VTD寫(xiě)入新的byte數(shù)組實(shí)際上就是一個(gè)byte數(shù)組的拷貝,其效率相當(dāng)?shù)母�,這就是所謂的增量更新(incremental update)。
關(guān)于VTD-XML的遍歷方式,它采用了LC (Location Cache),簡(jiǎn)單地說(shuō)就是將VTD以其深度作為標(biāo)準(zhǔn)構(gòu)建的一個(gè)樹(shù)形的表結(jié)構(gòu)。LC的entry也是64bits長(zhǎng)的數(shù)值類(lèi)型,前32bits代表一個(gè)VTD的索引(index),后32bits代表了這個(gè)VTD的第一個(gè)child的索引。利用這些信息就可以計(jì)算出任何一個(gè)你想要到達(dá)的位置了,關(guān)于具體的遍歷方法請(qǐng)參看官方網(wǎng)站的文章。基于這種遍歷方式的VTD-XML有與DOM不同的操作接口,這是可以理解的,并且,VTD-XML的這種遍歷方式可以在最少的幾步內(nèi)將你帶到你所需要的地方去,遍歷的性能十分突出。
總結(jié)
就像你上面看到的,VTD-XML有著迷人的特性,而如今的1.5版本中已經(jīng)加入了XPath的支持(只要可以遍歷,就可以支持XPath,這是早晚的事:-)),它的實(shí)用性已經(jīng)超越了當(dāng)今我們所想象的范圍了。另一個(gè)VTD-XML的超能力,就是基于它現(xiàn)在的處理方式,完全可以支持將來(lái)的Binary XML標(biāo)準(zhǔn),并通過(guò)Binary化將XML的應(yīng)用推向更高一層樓!這也是我目前所期待的!:-)
不過(guò),VTD-XML仍然有許多需要改進(jìn)與完善的地方,這方面值得我們努力與探討。
順便提一下,VTD-XML是開(kāi)源項(xiàng)目(GPL),目前有Java、C兩種平臺(tái)支持。如果你想在.NET試一試的話建議你使用IKVM(BSD style license)將VTD-XML轉(zhuǎn)換成.NET程序集,相信你會(huì)喜歡上它的!;-)
分享:解讀從實(shí)際應(yīng)用中了解WML學(xué)習(xí)自然語(yǔ)言的最好方法就是溶入相應(yīng)的語(yǔ)言環(huán)境在交流中學(xué)習(xí),學(xué)習(xí)一種編程語(yǔ)言的最好方法就是看例程。為了幫助大家建立wml應(yīng)用的第一印象,所以請(qǐng)大家先看第一個(gè)例子:
- xml創(chuàng)建節(jié)點(diǎn)(根節(jié)點(diǎn)、子節(jié)點(diǎn))
- WML開(kāi)發(fā)教程之 WAP網(wǎng)站服務(wù)器配置方法
- WMLScript的語(yǔ)法基礎(chǔ)
- 收集的WML Script標(biāo)準(zhǔn)函數(shù)庫(kù)
- WML教程之文本框控件Input
- 無(wú)線標(biāo)記語(yǔ)言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)
- xml文件的結(jié)構(gòu)解讀
- 關(guān)于XSL - XSL教程
- 選擇模式 - XSL教程 - 2
- XPath入門(mén) - XSL教程 - 3
- 匹配模式 - XSL教程 - 4
- 測(cè)試模式 - XSL教程 - 5
- 相關(guān)鏈接:
- 教程說(shuō)明:
Xml教程-新興XML處理方法VTD-XML介紹(2)
。