Java 中的 XML: 文檔模型,第一部分:性能研究 Java 中 XML 文檔模型的特性和性能 ![]() |
![]() |
![]() |
|
級別: 初級
Dennis M. Sosnoski
, 總裁, Sosnoski Software Solutions, Inc.
2001 年 9 月 01 日
在本文中,Java 顧問 Dennis Sosnoski 比較幾個(gè) Java 文檔模型的性能和功能。當(dāng)選擇模型時(shí),無法做到每次都權(quán)衡得很清楚,如果以后改變主意,則需要大量編碼來進(jìn)行切換。作者將性能結(jié)果放入特性集合的上下文中并遵循標(biāo)準(zhǔn),對所要求的正確選擇給出了一些建議。本文包含用于這組測試的幾張圖表和源代碼。
使用內(nèi)存中 XML 文檔的 Java 開發(fā)者可以選擇使用標(biāo)準(zhǔn) DOM 表示或幾個(gè) Java 特定模型中的任何一個(gè)。該靈活性已經(jīng)幫助將 Java 建立成 XML 工作的出色平臺。但是,由于不同模型數(shù)量的增加,已經(jīng)更加難以確定如何比較模型的功能、性能和易用性。
關(guān)于使用“Java 中的 XML”系列中的第一篇文章研究了 Java 中一些領(lǐng)先的 XML 文檔模型的特性和性能。它包括一組性能測試的結(jié)果(帶有可下載的測試代碼,請參閱 參考資料)。在系列中的第二篇文章將通過比較為實(shí)現(xiàn)同樣任務(wù)所使用的不同模型的樣本代碼來研究易用性問題。
Java 中的可用文檔模型數(shù)一直在增加。對于本文,我已經(jīng)涵蓋了最常用的模型和幾項(xiàng)選擇,這演示了那些可能還未被廣泛了解或使用的特別令人感興趣的特性。隨著“XML 名稱空間”的重要性增加,我已經(jīng)包含了僅支持該功能的模型。下面列出了帶有簡要介紹和版本信息的模型。
僅為說明本文中所使用的術(shù)語:
- 解析器是指解釋 XML 文本文檔結(jié)構(gòu)的程序
- 文檔表示是指程序用于內(nèi)存中文檔的數(shù)據(jù)結(jié)構(gòu)
- 文檔模型是指支持使用文檔表示的庫和 API
某些 XML 應(yīng)用程序根本不需要使用文檔模型。如果應(yīng)用程序可以通過文檔的一次遍歷搜集它需要的信息,則可能直接使用解析器。該方法可能需要增加一些工作量,但是它的性能總是優(yōu)于在內(nèi)存中構(gòu)建文檔表示。
DOM(“文檔對象模型”)是用與平臺和語言無關(guān)的方式表示 XML 文檔的官方 W3C 標(biāo)準(zhǔn)。對于任何 Java 特定的模型,它是很好的對照。為了值得與 DOM 標(biāo)準(zhǔn)分開,Java 特定模型應(yīng)該提供比 Java DOM 實(shí)現(xiàn)更優(yōu)越的性能和/或易用性的優(yōu)勢。
DOM 定義充分利用了 XML 文檔不同組件的接口和繼承性。這為開發(fā)者帶來了將公共接口用于幾個(gè)不同類型組件的優(yōu)勢,但是同時(shí)增加了 API 的復(fù)雜性。因?yàn)?DOM 是與語言無關(guān)的,所以接口不需要利用公共 Java 組件,例如,Collections 類。
本文涉及兩個(gè) DOM 實(shí)現(xiàn):Crimson 和 Xerces Java。Crimson 是基于 Sun Project X 解析器的 Apache 項(xiàng)目。它合并一個(gè)包含 DTD 支持的完整驗(yàn)證解析器。可以通過 SAX2 接口訪問該解析器,并且 DOM 實(shí)現(xiàn)可以與其它 SAX2 解析器一起工作。Crimson 是在 Apache 許可證下發(fā)布的開放源碼。用于性能比較的版本是 Crimson 1.1.1(jar 文件大小是 0.2MB),它包含有用于從文本文件的 DOM 構(gòu)建的 SAX2 解析器。
另一個(gè)測試的 DOM 實(shí)現(xiàn),即 Xerces Java 是另一個(gè) Apache 項(xiàng)目。初始時(shí),Xerces 基于 IBM Java 解析器(通常稱為 XML4J)。(當(dāng)前還處于早期 beta 測試版的重新開發(fā)的 Xerces Java 2 將最終繼承它。當(dāng)前版本有時(shí)稱為 Xerces Java 1。)如同使用 Crimson 一樣,可以通過 SAX2 接口和 DOM 來訪問 Xerces 解析器。然而,Xerces 不提供將 Xerces DOM 與不同的 SAX2 解析器一起使用的任何方法。Xerces Java 包含對 DTD 和 XML Schema 的驗(yàn)證支持(僅帶有對 Schema 支持的最小限制)。
Xerces Java 還支持 DOM 的延遲節(jié)點(diǎn)擴(kuò)展方式(請參考本文中的 延遲 Xerces或 Xerces def.),其中文檔組件初始時(shí)是以壓縮格式表示的,僅當(dāng)使用時(shí)才將它擴(kuò)展成完整的 DOM 表示。這種方式的用意是允許更快的解析并降低內(nèi)存的使用,尤其對于那些可能僅使用部分輸入文檔的應(yīng)用程序。與 Crimson 類似,Xerces 是在 Apache 許可證下發(fā)布的開放源碼。用于性能比較的版本是 Xerces 1.4.2(jar 文件大小是 1.8MB)。
JDOM 的目的是成為 Java 特定文檔模型,它簡化與 XML 的交互并且比使用 DOM 實(shí)現(xiàn)更快。由于是第一個(gè) Java 特定模型,JDOM 一直得到大力推廣和促進(jìn)。正在考慮通過“Java 規(guī)范請求 JSR-102”將它最終用作“Java 標(biāo)準(zhǔn)擴(kuò)展”。雖然實(shí)際將采用的格式仍在開發(fā)中,還是對兩個(gè) beta 測試版的 JDOM API 做了很大的更改,。從 2000 年初就已經(jīng)開始了 JDOM 開發(fā)。
JDOM 與 DOM 主要有兩方面不同。首先,JDOM 僅使用具體類而不使用接口。這在某些方面簡化了 API,但是也限制了靈活性。第二,API 大量使用了 Collections 類,簡化了那些已經(jīng)熟悉這些類的 Java 開發(fā)者的使用。
JDOM 文檔聲明其目的是“使用 20%(或更少)的精力解決 80%(或更多)Java/XML 問題”(根據(jù)學(xué)習(xí)曲線假定為 20%)。JDOM 對于大多數(shù) Java/XML 應(yīng)用程序來說當(dāng)然是有用的,并且大多數(shù)開發(fā)者發(fā)現(xiàn) API 比 DOM 容易理解得多。JDOM 還包括對程序行為的相當(dāng)廣泛檢查以防止用戶做任何在 XML 中無意義的事。然而,它仍需要您充分理解 XML 以便做一些超出基本的工作(或者甚至理解某些情況下的錯(cuò)誤)。這也許是比學(xué)習(xí) DOM 或 JDOM 接口都更有意義的工作。
JDOM 自身不包含解析器。它通常使用 SAX2 解析器來解析和驗(yàn)證輸入 XML 文檔(盡管它還可以將以前構(gòu)造的 DOM 表示作為輸入)。它包含一些轉(zhuǎn)換器以將 JDOM 表示輸出成 SAX2 事件流、DOM 模型或 XML 文本文檔。JDOM 是在 Apache 許可證變體下發(fā)布的開放源碼。用于性能比較的版本是 JDOM Beta 0.7(jar 文件大小是 0.1MB)它帶有用于從文本文件構(gòu)建 JDOM 表示的 Crimson SAX2 解析器。
雖然 dom4j 代表了完全獨(dú)立的開發(fā)結(jié)果,但最初,它是 JDOM 的一種智能分支。它合并了許多超出基本 XML 文檔表示的功能,包括集成的 XPath 支持、XML Schema 支持(當(dāng)前為 alpha 格式)以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過 dom4j API 和標(biāo)準(zhǔn) DOM 接口具有并行訪問功能。從 2000 下半年開始,它就一直處于開發(fā)之中,保留了最近發(fā)行版之間的現(xiàn)有 API。
為支持所有這些功能,dom4j 使用接口和抽象基本類方法。dom4j 大量使用了 API 中的 Collections 類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然 dom4j 付出了更復(fù)雜的 API 的代價(jià),但是它提供了比 JDOM 大得多的靈活性。
在添加靈活性、XPath 集成和對大文檔處理的目標(biāo)時(shí),dom4j 的目標(biāo)與 JDOM 是一樣的:針對 Java 開發(fā)者的易用性和直觀操作。它還致力于成為比 JDOM 更完整的解決方案,實(shí)現(xiàn)在本質(zhì)上處理所有 Java/XML 問題的目標(biāo)。在完成該目標(biāo)時(shí),它比 JDOM 更少強(qiáng)調(diào)防止不正確的應(yīng)用程序行為。
dom4j 使用相同方法作為 JDOM 輸出,這依靠 SAX2 解析器輸入處理,依靠轉(zhuǎn)換器將輸出處理成 SAX2 事件流、DOM 模型或 XML 文本文檔。dom4j 是在 BSD 樣式許可證下發(fā)布的開放源碼,該許可證本質(zhì)上等價(jià)于 Apache 樣式許可證。用于性能比較的版本是 dom4j 0.9(jar 文件大小是 0.4MB),帶有用于從文本文件構(gòu)建表示的受綁定 AElfred SAX2 解析器(由于 SAX2 選項(xiàng)設(shè)置,測試文件之一無法由 dom4j 使用用于 JDOM 測試的同一 Crimson SAX2 解析器來處理)。
Electric XML(EXML)是支持分布式計(jì)算的商業(yè)項(xiàng)目的附屬產(chǎn)物。它與目前為止討論的其它模型的不同之處在于,它只能適當(dāng)?shù)刂С?XML 文檔的子集,它沒有為驗(yàn)證提供任何支持并且有更嚴(yán)格的許可證。然而,EXML 的優(yōu)勢是大小很小并提供了對 XPath 子集的直接支持,因?yàn)樵谧罱鼛灼恼轮幸呀?jīng)將它提升其它模型的替代模型,所以通過該比較使它成為一個(gè)引人注意的候選。
雖然 EXML 通過使用抽象的基本類方法取得了某些相同效果,但它在避免使用接口方面使用與 JDOM 類似的方法(主要區(qū)別是接口為擴(kuò)展實(shí)現(xiàn)提供了更大的靈活性)。它與 JDOM 的不同之處還在于避免使用 Collections 類。該組合為其提供了非常簡單的 API,在許多方面類似于帶有附加 XPath 操作的 DOM API 簡化版本。
僅當(dāng)空白與非空白文本內(nèi)容鄰近時(shí),EXML 才在文檔中保留空白,這就將 EXML 限制成 XML 文檔的一個(gè)子集。標(biāo)準(zhǔn) XML 需要在讀取文檔時(shí)保留該空白,除非對文檔 DTD 可以確認(rèn)有無空白無關(guān)緊要。對于事先已經(jīng)知道空白無關(guān)緊要的許多 XML 應(yīng)用程序來說,EXML 方法工作得很好,但是它防止對于期望保留空白的文檔(例如,生成由瀏覽器顯示或查看的文檔的應(yīng)用程序)使用 EXML。(有關(guān)作者對于該主題的謙虛建議,請參閱副欄 使用空白的目的。)
這種空白的刪除會(huì)對性能比較產(chǎn)生誤導(dǎo)效果 ― 許多類型的測試范圍與文檔中的組件個(gè)數(shù)成比例,并且由 EXML 刪除的每個(gè)空白序列都是其它模型中的組件。EXML 包含在本文顯示的結(jié)果中,但是解釋性能差異時(shí)請記住這種影響。
EXML 使用集成的解析器依據(jù)文本文檔構(gòu)建文檔表示。除了通過文本方式外,它不提供從 DOM(或 SAX2)轉(zhuǎn)換或轉(zhuǎn)換成 SAX2(或 DOM)事件流的任何方式。EXML 是由 Mind Electric 在禁止將它嵌入某些類型的應(yīng)用程序或庫的受限許可證下發(fā)布的開放源碼。用于性能比較的版本是 Electric XML 2.2(jar 文件大小是 0.05MB)。
XML Pull Parser (XPP)是最近開發(fā)的,它演示了 XML 解析的不同方法。與 EXML 一樣,XPP 只能適當(dāng)支持 XML 文檔的子集并且不提供驗(yàn)證的任何支持。它同樣具有尺寸小的優(yōu)勢。這種優(yōu)勢再與拉回解析器方法結(jié)合,使它成為該比較中的良好替換項(xiàng)。
XPP 幾乎獨(dú)占地使用接口,但是它僅使用所有類中的一小部分。和 EXML 一樣,XPP 避免使用 API 中的 Collections 類。總的來說,它是本文中最簡單的文檔模型 API。
將 XPP 限制成 XML 文檔子集的局限性是它不支持文檔中的實(shí)體、注釋或處理指示信息。XPP 創(chuàng)建僅包含元素、屬性(包括“名稱空間”)和內(nèi)容文本的文檔結(jié)構(gòu)。這對于某些類型的應(yīng)用程序來說是一種非常嚴(yán)格的限制。但是通常它對性能的影響比 EXML 空白處理對性能的影響小。在本文中我僅使用了一個(gè)與 XPP 不兼容的測試文件,并且在帶有注釋的圖表中顯示了 XPP 結(jié)果,該注釋不包含該文件。
XPP 中的拉回解析器支持(本文中稱為 XPP 拉回)通過將解析實(shí)際上推遲到訪問文檔的一個(gè)組件時(shí)才進(jìn)行,然后按照構(gòu)造那個(gè)組件的需要對文檔進(jìn)行解析。該技術(shù)想實(shí)現(xiàn)允許非常快速的文檔顯示或分類應(yīng)用,尤其在需要轉(zhuǎn)發(fā)或除去(而不是對文檔進(jìn)行完全解析和處理)文檔時(shí)。該方法的使用是可選的,如果以非拉回型方式使用 XPP,它對整個(gè)文檔進(jìn)行解析并且同時(shí)地構(gòu)建完整的表示。
與 EXML 一樣,XPP 使用依據(jù)文本文檔構(gòu)建文檔表示的集成語法解析器,并且除了通過文本方式外,它不提供從 DOM(或 SAX2)轉(zhuǎn)換或轉(zhuǎn)換成 SAX2(或 DOM)事件流的任何方式。XPP 是具有 Apache 樣式許可證的開放源代碼。用于性能比較的版本是 PullParser 2.0.1 Beta 8(jar 文件大小是 0.04MB)。
![]() |
|
![]() ![]() |
![]()
|
本文中使用的性能比較基于對一組選中的 XML 文檔進(jìn)行的解析和使用,這些文檔試圖代表較大范圍的應(yīng)用程序:
- much_ado.xml,標(biāo)記成 XML 的莎士比亞戲劇。沒有屬性并且是相當(dāng)簡單的結(jié)構(gòu)(202K 字節(jié))。
- periodic.xml, XML 中的元素的周期表。一些屬性,也是相當(dāng)簡單的(117K 字節(jié))。
- soap1.xml,取自規(guī)范的樣本 SOAP 文檔。大量名稱空間和屬性(0.4K 字節(jié),每次測試需要重復(fù) 49 次)。
- soap2.xml,SOAP 文檔格式中的值列表。大量名稱空間和屬性(134K 字節(jié))。
- nt.xml,標(biāo)記為 XML 的“新約”。沒有屬性并且非常簡單的結(jié)構(gòu),大量文本內(nèi)容(1047K 字節(jié))。
- xml.xml,XML 規(guī)范,不帶 DTD 引用,在內(nèi)部定義所有實(shí)體。帶有大量混合內(nèi)容的文本樣式標(biāo)記,一些屬性(160K 字節(jié))。
關(guān)于測試平臺的更多信息,請參閱副欄 測試詳細(xì)信息并查看 參考資料以獲取用于測試的源代碼的鏈接。
除了非常小的 soap1.xml 文檔之外,所有評測時(shí)間都是指文檔的每次特定測試所經(jīng)歷的時(shí)間。在 soap1.xml 的情況下,評測的時(shí)間是 49 個(gè)連續(xù)的文檔測試(總數(shù)為 20K 字節(jié)文本的足夠副本數(shù))。
測試框架在一個(gè)文檔上運(yùn)行一個(gè)特定的測試多次(這里顯示運(yùn)行了 10 次),依此跟蹤該測試的最短時(shí)間和平均時(shí)間,然后繼續(xù)同一文檔上的下一個(gè)測試。完成對一個(gè)文檔的全部測試序列后,它對下一個(gè)文檔重復(fù)該過程。為防止文檔模型之間的交互,在執(zhí)行每個(gè)測試框架時(shí)僅測試一個(gè)模型。
HotSpot 以及類似于動(dòng)態(tài)優(yōu)化 JVM 的計(jì)時(shí)基準(zhǔn)程序是出了名的棘手的;測試序列中的小變化經(jīng)常導(dǎo)致計(jì)時(shí)結(jié)果發(fā)生很大變化。我已經(jīng)發(fā)現(xiàn)對于執(zhí)行特定代碼段的平均時(shí)間時(shí),確實(shí)如此;最短時(shí)間比較一致,正是我在這些結(jié)果中列出的值。可以參閱第一次測試(文檔構(gòu)建時(shí)間)的 平均和最短時(shí)間的比較。
文檔構(gòu)建時(shí)間測試檢查解析文本文檔和構(gòu)造文檔表示所需的時(shí)間。出于比較目的,已經(jīng)在圖表中包含了使用 Crimson 和 Xerces SAX2 解析的 SAX2 解析時(shí)間,因?yàn)榇蠖鄶?shù)文檔模型(除了 EXML 和 XPP 外的所有文檔)使用 SAX2 解析事件流作為文檔構(gòu)建過程的輸入。圖 1 描述了測試結(jié)果。
圖 1. 文檔構(gòu)建時(shí)間

對于大多數(shù)測試文檔來說,XPP 拉回的構(gòu)建時(shí)間太短以至于難以計(jì)算(因?yàn)樵谶@種情況下,實(shí)際上沒有對該文檔進(jìn)行解析),只顯示為非常短的 soap1.xml。對于該文件,拉回解析器內(nèi)存大小和相關(guān)的創(chuàng)建開銷使 XPP 顯得相對比較緩慢。這是因?yàn)闇y試程序?yàn)檎谶M(jìn)行解析的文檔的每個(gè)副本創(chuàng)建一個(gè)新的拉回解析器副本。在 soap1.xml 情況下,每次評測時(shí)間使用 49 個(gè)副本。分配與初始化這些解析器實(shí)例的開銷大于重復(fù)解析文本并構(gòu)建文檔表示的大多數(shù)其它方法所需的時(shí)間。
XPP 的作者在一個(gè)電子郵件的討論中指出,在實(shí)際應(yīng)用程序中,可以合用拉回解析器實(shí)例以重新使用。如果這樣做的話,soap1.xml 文件的開銷將明顯降到忽略不計(jì)程度。對于更大的文件,甚至不需要合用,拉回解析器創(chuàng)建開銷也可以變得忽略不計(jì)。
在本測試中,XPP(帶有完整解析),帶有延遲節(jié)點(diǎn)創(chuàng)建的 Xerces 和 dom4j 都顯示整體上的同等性能。延遲的 Xerces 對于較大的文檔尤其出色,但是對于較小的文檔的開銷較高 ― 甚至比常規(guī) Xerces DOM 高很多。在第一次使用文檔的一部分時(shí),延遲節(jié)點(diǎn)創(chuàng)建方法的開銷也較高,這會(huì)降低快速解析的優(yōu)勢。
對于較小的 soap1.xml 文件,所有格式(SAX2 解析、常規(guī) DOM 和延遲 DOM)的 Xerces 的顯得開銷較高。對于該文件 XPP(完全解析)尤其出色,對于 soap1.xml,EXML 甚至超過基于 SAX2 的模型。雖然 EXML 具有廢棄單獨(dú)的空白內(nèi)容的優(yōu)勢,但是總體上,它是本測試中最差的。
文檔遍歷時(shí)間測試檢查遍歷構(gòu)造的文檔表示所需的時(shí)間,按文檔順序遍歷每個(gè)元素、屬性和文本內(nèi)容段。它試圖表示文檔模型接口的性能,這對于從進(jìn)行過解析的文檔中重復(fù)訪問信息的應(yīng)用程序來說可能很重要。總體上,遍歷時(shí)間比解析時(shí)間快得多。對于只對解析過的文檔單次遍歷的應(yīng)用程序,解析時(shí)間將比遍歷時(shí)間更重要。圖 2 顯示了結(jié)果。
圖 2. 文檔遍歷時(shí)間

在本測試中,XPP 的性能大大超過了其余的測試對象。Xerces DOM 所花費(fèi)的時(shí)間大約是 XPP 的兩倍。雖然 EXML 具有廢棄文檔中單獨(dú)的空白內(nèi)容的優(yōu)勢,但是,EXML 花費(fèi)的時(shí)間幾乎是 XPP 的三倍。dom4j 在這張圖中處于中間位置。
使用 XPP 拉回時(shí),直到訪問文檔表示時(shí)才真正發(fā)生對文檔文本的解析。這導(dǎo)致第一次遍歷文檔表示時(shí)的開銷非常大(表中未顯示)。如果以后訪問整個(gè)文檔表示,則當(dāng)使用拉回解析方法時(shí),XPP 顯示性能的凈損失。對于拉回解析器來說,前兩個(gè)測試所需的總時(shí)間比使用 XPP 的常規(guī)解析長(長 20% 到 100%,這取決于文檔)。但是,當(dāng)還未完全訪問正在進(jìn)行解析的文檔時(shí),拉回解析器方法仍然具有可觀的性能優(yōu)勢。
帶有延遲節(jié)點(diǎn)創(chuàng)建的 Xerces 顯示了相似的行為,第一次訪問文檔表示時(shí)導(dǎo)致性能下降(圖中未顯示)。但是,在 Xerces 情況下,節(jié)點(diǎn)創(chuàng)建開銷大約與解析期間常規(guī) DOM 創(chuàng)建的性能差值相同。對于較大的文檔來說,用 Xerces 延遲的前兩次測試所需的總時(shí)間大致與使用帶常規(guī) DOM 構(gòu)建的 Xerces 所用的時(shí)間相同。如果在非常大的文檔(可能 10KB 或更大)上使用 Xerces,則延遲的節(jié)點(diǎn)創(chuàng)建似乎是一個(gè)好選擇。
這個(gè)測試檢查系統(tǒng)地修改構(gòu)造文檔表示所需的時(shí)間,其結(jié)果在 圖 3中顯示。它遍歷表示,刪除所有單獨(dú)的空白內(nèi)容并且用新添加的元素封裝每個(gè)非空白內(nèi)容字符串。它還向包含非空白內(nèi)容的原始文檔的每個(gè)元素中添加一個(gè)屬性。該測試試圖表示經(jīng)過一定范圍文檔修改后文檔模型的性能。如遍歷時(shí)間一樣,修改時(shí)間比解析時(shí)間短很多。因此,對于僅單次遍歷每個(gè)解析過的文檔的應(yīng)用程序來說,解析時(shí)間將更重要。
圖 3. 文檔修改時(shí)間

這次測試中 EXML 處于領(lǐng)先地位,但是由于在解析期間它總是廢棄單獨(dú)的空白內(nèi)容,它才比其它模型具有性能上的優(yōu)勢。這意味著在測試期間沒有要從 EXML 表示中進(jìn)行刪除的內(nèi)容。
在修改性能方面,XPP 僅次于 EXML,并且與 EXML 不同,XPP 測試包含刪除。Xerces DOM 和 dom4j 接近地處于中間位置,JDOM 和 Crimson DOM 模型的性能仍是最差。
這個(gè)測試檢查將文檔表示輸出成文本 XML 文檔所需的時(shí)間;結(jié)果顯示在 圖 4中。對于不專門使用 XML 文檔的任何應(yīng)用程序,該步驟似乎是整體性能的一個(gè)重要部分,特別是因?yàn)閷⑽臋n輸出為文本所需的時(shí)間總體接近于對文檔輸入進(jìn)行解析所需的時(shí)間。為使這些時(shí)間具有直接的可比性,該測試使用原始文檔,而沒有使用由前面的測試所生成的已修改文檔。
圖 4. 文本生成時(shí)間

文本生成時(shí)間測試表明各模型之間的差別小于前面測試中各項(xiàng)的差別,Xerces DOM 性能最好,但領(lǐng)先不多,JDOM 性能最差。EXML 的性能優(yōu)于 JDOM,但是這同樣是由于 EXML 廢棄空白內(nèi)容。
許多模型提供了控制文本輸出格式的選項(xiàng),并且一些選項(xiàng)似乎影響文本生成時(shí)間。這個(gè)測試只使用每個(gè)模型的最基本的輸出格式,因此結(jié)果只顯示缺省性能而不顯示最好的可能性能。
這個(gè)測試檢查用于文檔表示的內(nèi)存空間。這對于使用大文檔或同時(shí)使用多個(gè)較小文檔的開發(fā)者來說,意義尤為重要。圖 5 顯示這個(gè)測試的結(jié)果。
圖 5. 文檔內(nèi)存大小

內(nèi)存大小結(jié)果與計(jì)時(shí)測試不同,因?yàn)樾〉?soap1.xml 文件顯示的值表示文件的單個(gè)副本而不表示在計(jì)時(shí)評測中使用的 49 個(gè)副本。在大多數(shù)模型中,用于簡要文檔的內(nèi)存太小以至于無法在圖的刻度上顯示。
除了 XPP 拉回(直到訪問它時(shí)才真正構(gòu)建文檔表示)之外,與一些計(jì)時(shí)測試中顯示的差別相比,內(nèi)存大小測試中模型之間的差別相對較小。延遲的 Xerces 具有最緊湊的表示(當(dāng)?shù)谝淮卧L問表示時(shí)將它擴(kuò)展成基本 Xerces 大小),緊接著是 dom4j。雖然 EXML 廢棄包含在其它模型中的空白內(nèi)容,但是它仍具有最不緊湊的表示。
因?yàn)榧词棺罹o湊的模型也要占用大約原始文檔文本大小(以字節(jié)計(jì))四倍的空間,所以對于大文檔來說,所有模型似乎都需要太多的內(nèi)存。通過提供使用部分文檔表示的方法,XPP 拉回和 dom4j 為非常大的文檔提供了最好的支持。XPP 拉回通過僅構(gòu)建實(shí)際被訪問的表示部分完成該任務(wù),而 dom4j 包含對基于事件處理的支持,使得一次只構(gòu)建或處理文檔的一部分。
這些測試評測文檔表示的 Java 序列化的時(shí)間和輸出大小。這主要涉及那些使用 Java RMI(“遠(yuǎn)程方法調(diào)用”)在 Java 程序之間傳送表示的應(yīng)用程序(包括 EJB (Enterprise JavaBean) 應(yīng)用程序)起作用。在這些測試中,僅包含了那些支持 Java 序列化的模型。下列三張圖顯示了該測試的結(jié)果。
圖 6. 序列化輸出時(shí)間

圖 7. 序列化輸入時(shí)間

圖 8. 序列化文檔大小

dom4j 顯示了輸出(生成序列化的格式)和輸入(從序列化的格式重新構(gòu)建文檔)的最好的序列化性能,而 Xerces DOM 顯示了最差的性能。EXML 所花費(fèi)的時(shí)間接近 dom4j,但是 EXML 還是具有在表示中使用較少數(shù)量對象的優(yōu)勢,因?yàn)樗鼜U棄空白內(nèi)容。
如果將文檔輸出成文本然后進(jìn)行解析以重新構(gòu)建文檔,而不是使用 Java 序列化,則所有性能 ― 時(shí)間和大小 ― 都會(huì)好得多。這里的問題是作為大量唯一的小對象的 XML 文檔表示的結(jié)構(gòu)。Java 序列化無法有效處理這種類型的結(jié)構(gòu),這導(dǎo)致時(shí)間和輸出大小的開銷都很高。
可以設(shè)計(jì)比文本表示小且比文本輸入和輸出快的文檔序列化格式,但是只能通過繞過 Java 序列化來完成。(我有一個(gè)項(xiàng)目實(shí)現(xiàn) XML 文檔的這種定制的序列化,在我公司的 Web 站點(diǎn)上可以找到其開放源碼,請參閱 參考資料。)
![]() ![]() |
![]()
|
不同的 Java XML 文檔模型各有所長,但是從性能觀點(diǎn)來看,有些模型具有明顯的優(yōu)勢。
在大多數(shù)方面,XPP 性能處于領(lǐng)先地位。盡管 XPP 是一種新模型,但是對于不需要驗(yàn)證、實(shí)體、處理指示信息或注釋的中間件類型應(yīng)用程序來說,它是非常好的選擇。它尤其適用于作為瀏覽器小應(yīng)用程序或在內(nèi)存受限的環(huán)境下運(yùn)行的應(yīng)用程序。
雖然 dom4j 沒有與 XPP 同等的速度,但是,它確實(shí)提供了具備更標(biāo)準(zhǔn)化的優(yōu)越性能和功能更全的實(shí)現(xiàn),包括對 SAX2、DOM 甚至 XPath 的內(nèi)置支持。雖然 Xerces DOM(帶有延遲的節(jié)點(diǎn)創(chuàng)建)對于小文件和 Java 序列化性能不佳,但是在大多數(shù)評測時(shí)仍然出色。對于常規(guī) XML 處理,dom4j 和 Xerces DOM 都是很好的選擇,對它們的選擇取決于您認(rèn)為是特定于 Java 的特性更重要還是跨語言的兼容性更重要。
JDOM 和 Crimson DOM 在性能測試時(shí)一直表現(xiàn)不佳。在小文檔情況下還值得考慮使用 Crimson DOM,而 Xerces 表現(xiàn)很差。雖然 JDOM 的開發(fā)者已經(jīng)說明他們期望在正式發(fā)行版前專注性能問題,但是從性能觀點(diǎn)來看,它確實(shí)沒有值得推薦之處。然而,如果不進(jìn)行 API 的重新構(gòu)建,JDOM 可能難以達(dá)到與其它模型匹配的性能。
![]() |
|
EXML 非常小(以 jar 文件大小為單位)并且在一些性能測試中表現(xiàn)良好。雖然 EXML 具有刪除單獨(dú)空白內(nèi)容的優(yōu)勢,但是在性能方面不如 XPP。除非您需要 EXML 支持而 XPP 缺少的一種特性,否則在內(nèi)存受限的環(huán)境下,XPP 可能是更好的選擇。
雖然 dom4j 性能最好,但是,當(dāng)前沒有一種模型能為 Java 序列化提供良好性能。如果需要在程序之間傳遞文檔,通常的最佳選擇是將文檔寫成文本然后進(jìn)行解析以重新構(gòu)建表示。將來,定制序列化格式可能提供一個(gè)更好的選擇。
![]() ![]() |
![]()
|
我已經(jīng)涵蓋了一些文檔模型的基本特性,并且顯示了幾種類型文檔操作的性能評測。請記住,雖然,性能只是選擇文檔模型的一個(gè)因素。對于大多數(shù)開發(fā)者,可用性至少與性能一樣重要,并且這些模型使用不同的 API 都可能有喜歡這個(gè)而不喜歡那個(gè)的理由。
在后續(xù)文章中將集中研究可用性,其中我將比較用于完成這些不同模型中相同操作的樣本代碼。請檢查本比較的第二部分。當(dāng)您等待時(shí),可以通過下面的論壇中的鏈接提出您對本文的評論和問題與大家共享。
![]() ![]() |
![]()
|
- 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文.
- 參加關(guān)于本文的 論壇。
- 如果您需要背景知識,請嘗試 developerWorks的教程 XML Java 編程、 理解 SAX和 理解 DOM。
- 從 下載頁面下載用于本文的測試程序和文檔模型庫。
- 在測試程序的 主頁上查看更新的測試和測試結(jié)果。
- 獲取作者關(guān)于 XML Serial (XMLS) encoding工作的詳細(xì)信息作為 Java 序列化的替代項(xiàng)。
- 研究或下載本文中討論的 Java XML 文檔模型:
- IBM WebSphere Application Server 包含基于 Xerces Java 的 XML4J 解析器。可在 WAS Advanced edition 3.0 online documentation中找到關(guān)于產(chǎn)品 XML 支持的 how-to 信息。
![]() ![]() |
![]()
|
![]() |
||
|
![]() |
Dennis Sosnoski( dms@sosnoski.com)是西雅圖地區(qū) Java 咨詢公司 Sosnoski Software Solutions, Inc.的創(chuàng)建者和首席顧問。他具有 30 多年的專業(yè)軟件開發(fā)經(jīng)驗(yàn),最近幾年,他集中研究服務(wù)器方 Java 技術(shù),包括 servlet、Enterprise JavaBeans 和 XML。他已經(jīng)多次演示了 Java 性能問題和常規(guī)服務(wù)器端的 Java 技術(shù),他還是 Seattle Java-XML SIG的主席。 |