`
txxg
  • 浏览: 20239 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

(转贴)使用VTD-XML简化XML处理-克服DOM及SAX缺点的新选择

    博客分类:
  • Old
阅读更多

作者:Jimmy Zhang;(原文地址:http://www.javaworld.com/javaworld/jw-03-2006/jw-0327-simplify.html)

翻译:rainy14f(作者的blog:http://shaofan.blogjava.net/)

概要

做为下一代WEB应用的推动性技术,XML相当简单,易学易用。然而,当前的XML处理技术却非如此。Document Object Model和Simple API for XML都比较慢,低效,且不易于使用。VTD-XML,作为下一代的XML处理模型,提供超越DOM和SAX的广泛用途和更佳选择,不仅可以简化XML编程,也使选择XML处理模型更加容易。这篇文章通过最近的基准测试数据和示例程序来突显它的关键性的技术优势,显示出VTD-XML将可能解决长期以来困扰企业架构的,在DOM和SAX之间进行抉择的问题。

自从诞生以来的八年里,XML作为一个开放,半结构化的数据格式和WEB应用的数据交换工具,已取得了长足进步。由于它的简易性和良好的可读性,XML受到开发人员的热烈欢迎,并且已经成为了企业架构不可分割的一部分。

虽然很难说清XML到底有多少种不同的应用,但至少有一点是肯定的:XML解析处理已成为各种工作的先决任务。实际上,决定使用哪种解析器也经常是企业开发者在项目中必须首先解决的问题之一。长久以来,这其实就是在两种 XML处理模型之间做出选择:Document Object Model (DOM) 和 Simple API for XML (SAX)。

粗看之下,DOM和SAX各自的优缺点刚好形成互补。DOM使用内存保存对象结构;而SAX则基于事件并且不使用内存来存储任何数据。因此,DOM比较适合文档较小而数据访问模式复杂的情况,相反情况下,则使用SAX。

然而事实却并不这么单纯。很多情况下,开发者不情愿使用复杂的SAX,但又不得不用,因为没有其他选择。此外,即使XML文件的大小只是稍微大于几百K,DOM的内存开销和性能迟滞也会成为棘手的障碍,使得程序无法达到项目所要求的最低性能目标。

那么是否SAX的性能真得好得多?实际上,SAX所吹嘘的解析性能――通常比DOM快几倍――常常是不现实的。事实显示,SAX笨拙的,只能往前的解析不仅在使用时相当不便,而且当文档结构稍微复杂时,也会遇到性能问题。如果开发人员不想多次扫描文档,那么就需要对文档进行缓冲,或构建自己的对象模型。

不管使用哪种方法,性能都会成为问题,正如Apache Axis所证明的那样。在Axis的FAQ页面,它声称使用了SAX来构建高性能的实现,但它仍然使用了他们自己的和DOM非常相像的对象模型。但与它的前任 (Apache SOAP) 相比,这种做法并没有带来明显的性能提升。而且,SAX无法处理XPath,一般来说也无法驱动XSLT (Extensible Stylesheet Language Transformation) 的处理。因此,SAX仍然无法真正解决XML处理中的问题。

为了寻找一个更易用的SAX的取代方案,越来越多的开发人员开使转向StAX (Streaming API for XML)。与SAX相比,StAX使用从XML文件中提取标记的方法,而不是回调。这种方案显著地改善了可用性,但一个基本的问题仍然存在――StAX的只能往前的解析对于程序员依然不便,而且存在隐藏的性能损失。

底线是:任何想得到广泛应用的XML处理模型,必需能够完整体现XML的层次结构。这是因为,XML是被设计为在WEB上传输复杂数据的,因此完整展现它的结构信息也是它的任务之一。

VTD-XML改变了游戏

假设我们要从头开始一个XML处理过程,并克服上面提到的DOM和SAX的种种缺点,那么这个新的模型应该具有以下属性:

* 随机访问能力:处理模型应该允许开发人员方便访问文档的某种层次结构,比如,使用XPath,或手动。
* 高性能:性能上与DOM及SAX相比,应有显著提高,而且这个“性能”应该是真实的,就是说,应该把建立文档层次结构的时间也算上。
* 低内存占用率:要使该模型能够被广泛应用于各种场景,不管文件的大小,那它就必须能够以最低的内存消耗来表现XML的结构。

VTD-XML就是一个实现了这些目标的下一代的开源XML处理模型。它相比于DOM和SAX有着本质和全面的改进。VTD-XML的一个关键优化是非提取符号(non-extractive tokenization)。在其内部,VTD-XML在内存中保存完整及未解码的XML消息,并使用一个二进制编码规范来唯一地表示每个符号。这种规范被称为Virtual Token Descriptor(虚拟符号描述符)。每个VTD记录都是一个64字节的整数,它对XML中符号的长度,起始偏移量,类型,嵌套深度进行了编码。

再简单地介绍一下VTD-XML的历史,也许你会感兴趣:最初这个概念是被用来在特定硬件设备上使用,以使这些硬件(如路由器,交换机)可以高速处理XML,比如FPGA,ASIC。此后,VTD-XML项目组决定使它开源,并于2004年五月发布了VTD-XML的最初版本,0.5版,用JAVA实现。从那时起。VTD-XML经历了多次改进并越来越成熟。在0.8版本中,C语言版本的VTD-XML与JAVA版同时发布。在1.0版中引入了对XPath的内建支持,于2005年10月发布。最新的版本是1.5版,它的解析引擎被重新编写以实现更强的模块化和更高的性能。

同样,在这个版本中还出现了一个新的特性,叫作缓冲重用。它的基本概念是,当XML应用需要通过网络连接来反复地读入XML文档时,该应用会重用在第一次处理中分配的内存缓冲。换句话说,即一次分配,多次使用。就VTD-XML来讲,这个特性完全消除了在处理XML过程中建立对象和垃圾回收的开销(在DOM和SAX中占用50%至80%的开销)。在该项目的网站上,提供有最新的软件下载和深层技术说明。


一个简短例子

为了使你更好地了解VTD-XML编程的风格,本文首先对用VTD-XML和DOM解析和访问一个简单的XML文件进行对比。该文件名为test.xml,内容如下:

<purchaseOrder orderDate="1999-10-21">
       <item partNum="872-AA">
         <productName>Lawnmower</productName>
         <quantity>1</quantity>
         <USPrice>148.95</USPrice>
       </item>
</purchaseOrder>



VTD-XML版本的程序如下:

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



实现同样功能的DOM版本的程序:

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



像以上所展示的那样,VTD-XML使用基于游标的API来访问XML层次结构。相比之下,DOM API通过请求对象的引用来达成同样目标。VTD-XML的项目网站提供更多详细的技术资料和示例程序。

VTD-XML的基准测试

下面,我们来比较一下VTD-XML一些流行的XML解析器的性能和内存占用情况。值得注意的是,多数包含基准测试数据的文章,如Dennis Sosnoski于2002年4月发表在JavaWorld上的“XML Documents on the Run”,都是多年前的文章。自那以后,如摩尔定律所示,更好更快的硬件大量涌现并越来越便宜。同时,XML解析与JVM技术也并未止步不前――在一些关键领域做出了改进。

测试设置
测试平台是Sony VAIO笔记本电脑,使用Pentium M 1.7 GHz处理器(2MB L2 cache),512MB DDR2内存。前端总线频率为400MHz。操作系统为Windows XP Professional Edition with Services pack 2。JVM版本为1.5.0_06。
对以下XML解析器的最新版本进行了基准测试:
*Xerces DOM 2.7.1, 带有及不带有延迟节点扩展(deferred node expansion)
*Xerces SAX 2.7.1
*Piccolo SAX 1.04
*XPP3 1.1.3.4.O
*VTD-XML 1.5, 带有及不带有缓冲重用

在测试中我使用了大量不同大小和不同复杂程度的XML文档。从文档大小上,我把它们分为三类:小文件(小于10KB);中文件(10KB至1MB);大文件(大于1MB)。
在全部的性能度量中我都使用了服务器的JVM来获取最高性能。在这些测试中,基准测试程序首先会多次解析或访问文档,使JVM对字节码进行即时动态优化,之后才取得性能的平均值作为最终结果。为了减少由于磁盘IO导致的时间差别,基准测试程序在测试运行之前已经把XML文件读入到内存中。

注意:有兴趣的读者可以从资源下载基准测试程序。

吞吐量对比解析
本节在延迟时间和吞吐量上对XML解析性能进行描述。要注意的是VTD-XML与DOM可直接进行比较,而与SAX或Pull直接对比就很不公平,因为它们不在内存中构建任何层次结构。因此SAX和Pull的性能在此只作为额外参考。
吞吐量

image
图 1. 小文件.
    
image
图 2. 中文件.
    
image
图 3. 大文件.

延迟时间对比
表 1. 小文件
image

表 2. 中文件
image

表 3. 大文件
image

内存占用率对比
因为SAX和Pull不在内存中构建任何数据结构,所以这项测试只有与DOM的对比才有意义。因此,本节对倍加系数(multiplying factor)进行衡量,该系数为内存占用率与大文件的文件大小之比(内存占用对大文件特别重要)。

image
图 4.

访问性能对比
本节从延迟时间上展示VTD-XML与DOM 的访问性能。延迟时间是指访问文档中每个节点所花的时间。为了遍历所有节点,DOM依赖于nodeInterator接口,而VTD-XML则调用AutoPilot类的成员方法selectElement(…)与iterate(…)。如所预期的一样,访问速度比解析速度要快得多。对VTD-XML,访问时间开销在解析时间开销的15%到30%之间。对DOM,该数字为5%到7%。这并不说明VTD-XML的访问速度慢于DOM。这完全是因为VTD-XML有着非常快的解析速度。

表 4. 小文件
image

表 5. 中文件
image

表 6. 大文件
image

结果分析
在Dennis Sosnoski四年前发表于JavaWorld的文章中,Piccolo是众多SAX实现中的赢家。现在这得到了改变:最新的Xerces击败众多对手成为性能最好的SAX解析器。测试结果也显示,与Xerces相比,XPP3也有相当不错的性能,不比前者相差很多。
另外,有趣的是,当文件较小时,DOM与SAX的解析性能差距并不像在解析大文件时的相差那么大。在小文件的情况下,DOM的延迟节点扩展导致比使用完全节点扩展要差的解析性能。

而VTD-XML的出众性能使它完全胜过其他任何解析器,这使它自成一级。真正的比较只是存在于使用缓冲重用的VTD-XML及不使用缓冲重用的VTD-XML之间。内存占用率上的重大优势使得VTD-XML可以被用于处理大XML文档,并且对任意大小的文件都有较好的性能。

结论

VTD-XML是一种全新的,下一代的XML解析器。它解决了许多目前困扰DOM和SAX的问题。VTD-XML高性能与低内存占用的结合意味着:首先,DRAM已经相当便宜,如果不是完全没有空间存放XML文档,那就没有多少理由使用SAX;其次,使用VTD-XML使得应用变得更加简单,更快。它对各种大小的文件的适应性,使得选择一个合适的XML处理模型变得简单,而开发人员也不必再在完全不同的DOM和SAX中进行切换了;最后,VTD-XML可以为长久以来对XML的不满提供一个令人信服的答案。比如,VTD-XML内建了本地XML索引的能力,也许可以永久改变认为XML速度慢的看法。正由于它的性能优势,VTD-XML应该标志着“10倍速XML”时代的到来。更重要的是,VTD-XML的下一站,只在咫尺之遥,那就是“100倍速XML”。

资源
*VTD-XML:http://vtd-xml.sf.net/
*Apache Axis FAQ:http://ws.apache.org/axis/faq.html#faq1
*下载基准测试程序:http://sourceforge.net/project/showfiles.php?group_id=110612

 
分享到:
评论

相关推荐

    vtd-xml vtd-xml vtd-xml

    5. **性能优势**:与DOM和SAX解析器相比,VTD-XML在处理大文件时具有显著的优势。DOM解析器会将整个XML树加载到内存中,占用大量资源;SAX是事件驱动的,适合流式处理,但不支持随机访问。而VTD-XML则兼顾了随机访问...

    VTD-XML 不同于SAX和DOM的XML高效解析器

    在处理XML时,有多种解析器可供选择,包括SAX(Simple API for XML)、DOM(Document Object Model)以及我们今天要讨论的主题——VTD-XML。 **VTD-XML解析器** VTD-XML是由XimpleWare公司开发的一种高效的XML解析...

    vtd-xml XML解析工具

    通过使用VTD-XML,开发者可以轻松地实现XML文档的搜索、分析、转换和更新,而无需深入理解DOM或SAX解析模型的复杂性。 在Java环境中,XimpleWare公司提供的VTD-XML库包含了一系列API,如`VTDGen`用于解析XML文档并...

    vtd-xml+教程+源码+事例+集合.zip

    与DOM和SAX解析器相比,VTD-XML在处理大型XML文档时具有更高的效率,因为它不需要将整个文档加载到内存中。 2. VTD-XML的基本概念: - VTD:Variable Token Descriptor,用于表示XML文档的片段,每个VTD代表XML...

    vtd-xml+教程+源码+事例+集合

    - **XPath支持**:VTD-XML支持XPath表达式,但可能不如DOM或SAX解析器那样全面,需要了解其XPath实现的限制。 - **性能优化**:VTD-XML设计的目标就是高性能,但在实际使用中,还需要根据具体场景进行优化,比如合理...

    VTD-XML.zip_VTD_VTD-XML_instruction_zip

    这个压缩包“VTD-XML.zip_VTD_VTD-XML_instruction_zip”包含了关于VTD-XML的详细使用指南,特别是其中的“VTD-XML.pdf”文件,应该是该库的用户手册或教程。 XML(Extensible Markup Language)是用于存储和传输...

    vtd-xml源码+例程

    VTD-XML是一种高效、轻量级的XML处理库,由XimpleWare公司开发,它提供了C和Java两种版本。这个压缩包包含了VTD-XML的C++源码和一些例程,对于想要深入理解VTD-XML工作原理或者进行二次开发的开发者来说,是一个非常...

    VTD-XML c源码及vs2013编译生成的lib

    VTD-XML库以其基于变量的文档定位(Variable To Document)技术而闻名,它提供了对XML文档的强大导航、解析和操作功能,且性能优于DOM和SAX解析器。 VTD-XML库的核心理念是通过预处理XML文档并创建一个索引,使得...

    VTD-XML技术解析XML实例

    VTD-XML是一种高效、灵活且内存友好的XML处理库,尤其在大型XML文档处理方面表现出色。它是由VTD Tech公司开发的,主要用于XML的导航、解析和操作。VTD-XML技术的核心是虚拟XML索引(Virtual Token Descriptor, VTD...

    vtd-xml相关资料.zip

    VTD-XML是一种高效、轻量级的XML解析技术,由XimpleWare公司开发,它在处理大型XML文档时表现出显著的优势,相比DOM和SAX解析方式,VTD-XML在速度和内存占用方面有着更优的表现。VTD(Virtual Token Descriptor)是...

    vtd-xml example

    VTD-XML是一个高效、灵活且功能强大的XML处理库,由VTD-XML技术创始人Harold Abelson开发。它主要用于XML文档的随机访问、解析、导航和修改。VTD-XML利用一种叫做Variable Length Tokenized Index(可变长度标记化...

    新兴XML处理方法VTD-XML介绍

    针对DOM和SAX存在的问题,VTD-XML提供了一种新的非提取式(non-extractive)XML解析方法,有效地解决了传统解析方式中的诸多效率瓶颈。 **非提取式解析模式**:VTD-XML采用了非提取式的解析方式,即解析过程中不会...

    VTD-XML解析软件.zip

    相比传统的DOM(Document Object Model)和SAX(Simple API for XML)解析器,VTD-XML提供了一种全新的、随机访问XML文档的方法,这使得它在性能和内存效率上具有显著优势。 1. **随机访问能力**:VTD-XML的核心...

    VTD-XML-Example:使用 VTD-XML 解析器与 volley 并与 pull 解析器进行比较的示例

    VTD-XML提供了多种API,如导航、选择、更新和复制XML数据,使得XML处理更加灵活和高效。 接下来,我们来看看Volley。Volley是一个Android网络请求库,它的设计目标是简化网络请求的流程,提高性能并优化Android应用...

    基于多核处理器的VTD-XML节点查询执行性能优化.pdf

    VTD-XML是一种高效的XML处理方法,相比DOM和SAX,它具有更优的性能表现。 文章首先介绍了XML的重要性,作为Web应用中的核心数据格式,XML广泛应用于SOA架构的数据交换等场景。然而,XML处理,特别是解析、查询和...

    vtd-xml-2.6-java-src.rar_VTD-XML_www.vtd2cn_断词

    VTD-XML 是一种基于 Java* 的新型开放源代码 XML 处理 API,能够解决当前 XML 处理模型的许多问题。此方案目前属于 Sourceforge* 一部分,可在此处*找到。通过本演示*,您将熟悉这些基本的概念。仅凭这一点,我们还...

    VTD-XML: The Future of XML Processing-开源

    总之,VTD-XML作为一种创新的XML处理工具,不仅提供了高效的处理机制,而且具备优秀的内存管理特性,为开发者处理XML数据提供了新的选择。通过开源的方式,VTD-XML促进了XML技术的进一步发展,并且为社区带来了更多...

    使用VTD-XML的无模式C#-XML数据绑定

    标题中的“使用VTD-XML的无模式C#-XML数据绑定”指的是在C#编程环境中,利用VTD-XML库实现的一种XML数据绑定技术,它允许开发者在没有XML架构(Schema)的情况下处理XML文档。VTD-XML库是一个高效且灵活的XML处理...

    VTD-XML:面向未来的XML处理(第一部分)

    2. **内存效率**:与DOM模型相比,VTD-XML在内存使用上更为优化,尤其适合处理大型XML文档。 3. **强大的XPath支持**:VTD-XML提供了完整的XPath 1.0支持,允许用户通过表达式轻松地查找和提取XML数据。 4. **XML...

    简化XML处理详解

    XML,即可扩展标记语言,已经成为软件开发领域...与DOM和SAX相比,VTD-XML在易用性、性能和内存管理方面都有显著优势,是XML处理领域的重要突破,对于需要高效处理XML的开发者来说,VTD-XML无疑是一个值得考虑的选择。

Global site tag (gtag.js) - Google Analytics