`
fyd222
  • 浏览: 104040 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

XML 处理模式性能问题

阅读更多

 

XML 性能问题
作者:Jimmy Zhang

本文介绍了 VTD-XML*,这是一种全新开放源代码的非提取性的(non-extractive) XML 处理 API。本文还深入探讨了 VTD-XML 技术细节,并阐述了 VTD-XML 能够综合 DOM 和 SAX 的优势,独一无二地支持不断更新和“一次解析,多次使用”的原因。

还记得有多少人曾在私下或设计大会上跟您抱怨过 XML 的性能吗?事实上,正是由于 XML 性能不佳以及冗长等缺点,万维网联盟(W3C)于去年做出成立二进制 XML 评定工作组的决定。

XML 被设计成一种互联网的数据交换格式。而冗长的特点是由 XML 的多核心优势所带来的。如:半结构化、开放式互操作、以及可以被人读懂(human-readable)等优势。幸运的是,随着带宽价格不断下降以及容量更加充裕,过去的难题在今天看来可能并不是什么大问题,在未来可能更算不上是问题了。

与冗长相比,XML 的性能则完全是另一回事。试想:XML 不会跑,它既没有腿也没有轮子;XML 也不真正执行,它根本就不是“.exe”文件。实际上,软件开发人员都选择一种处理模式来读取、写入或更新 XML 数据。严格地说来,性能优劣并不是 XML 本身的问题,而是 XML 处理模式的问题。因此,了解一些与当前 XML 处理模式有关的技术问题很有必要,例如:文档对象模型(DOM)和 SAX。


DOM 和 SAX 技术分析
DOM 是一个基于树结构的内存中 XML 处理 API,其设计独立于平台和语言。开发人员可以使用 DOM 创建 XML 文档,浏览其结构,添加、更改或删除其网元。DOM 中一个非常重要的概念就是节点接口模型:DOM 的分级表示中的每个数据对象均可实现节点接口。由于 DOM 加载内存中所有内容,并提供 XML 数据的分级视图,因此开发人员通常会感觉 XML 的使用非常简单方便。其缺点是构建 DOM 树所用时间较长,并且需要占用大量内存(一般大小是 XML 文档的 5 至 10 倍)。

导致 DOM 性能问题的根源在于面向对象的程序设计(OOP)存在薄弱环节。创建 DOM 树涉及大批对象的动态分配,用时下流行的 OOP 语言来说,就是非常昂贵。更糟的是,当这些对象越界时,需要像收集垃圾一样将其收集起来。并且,分配大批对象会导致在合计每对象内存开销时出现严重的内存膨胀(memory bloat)现象。

另一方面,SAX 用于查找 DOM 的内存使用浪费问题。为了达到这一目的,SAX 将一个低级的标记程序(tokenizer)直接导出至调用它的应用程序。SAX 解析器本身并不构建 XML 文档的任何内存中表达。SAX 的内存使用率较低,且不会随着文档大小的增加而扩展,但糟糕的是 SAX 很难使用。SAX 不会在内存中建立树,使用 SAX 的开发人员通常需要将其应用程序调整为事件驱动形式,以适应解析例程。这就会创建冗长且难以维护的代码,从而加重开发人员的负担。

对于需要重复访问 XML 中数据要素的应用程序,SAX 还带来了以下难题:要么对应用程序进行编码以多次扫描 XML 文档,要么创建内存中结构。尽管 SAX 的原始性能很出色,但多次扫描文档会大大降低其相比 DOM 的性能优势。如果有其它选择,您会发现您其实是在构建 DOM。因此,为何不一开始就使用 DOM 呢?

总之,XML 处理模型性能的提高不应以降低可用性为代价。分配大量对象会造成随机访问 API 性能及内存开销。

为什么说了解 DOM 和 SAX 问题非常重要?因为解决问题的方法通常都是寻找多种不同的途径来完成同一个任务。在下文中您将会看到,构成传统 XML 处理技术的许多步骤和设计决定都很简单,而且有时毫无特别之处,而将这些简单的方法综合起来往往能够达到同样的目标并获得更好的结果。


了解 VTD-XML
简介

VTD-XML 是一种基于 Java* 的新型开放源代码 XML 处理 API,能够解决当前 XML 处理模型的许多问题。此方案目前属于 Sourceforge* 一部分,可在此处*找到。通过本演示*,您将熟悉这些基本的概念。仅凭这一点,我们还不能认为 VTD-XML 是专门为此而设计的,因为从第一步——断词(tokenization)开始,它就引入了大量优化技术。

基于偏移和长度的“Non-Extractive”断词(tokenization)。

传统上第一步,XML 分析器将输入的 XML 文档拆分为多个包含相关文本数据的标记(token)。然后,该解析器或将这些标记作为 SAX 事件传送给用户,或都构建基于分级数据结构的内存中对象。断词(tokenization)后,该解析器通常会将输入源文档丢弃。这些标记,即字符串,就是解析过程中分配的字符的空结束阵列。这种断方式即“extractive”断词,解析器实际上是将文本内容从输入文档提取到动态创建的字符串中。

但是,为了实现断词目的,还有一种简单的方法,即仅用开始偏移和长度来描述标记。这种方法也需要将源文件以禁止解码的格式完整保存在内存中。基本上,解析器将 XML 文档视为一个大标记筐,并创建详细描述 XML 中标记位置的地图。此种断词方式称为“non-extractive”,解析器会将标记与原文中保持一样。

阐述“non-extractive”断词方式工作原理的最佳途径就是将其与一般使用场景中的传统“extractive”标记进行比较:

  • 字符串比较: 使用 extractive 断词,开发人员使用 C 语言的"strcmp" 功能(见<string.h />) 来比较“extractive”标记和已知字符串。而使用“non-extractive”断词,开发人员只需使用<string.h>中 C 的“strncmp”功能即可。
  • 字符串到数字数据的转换: 其它经常使用的宏,如 "atoi" 和 "atof" 可以用 non-extractive 标记进行修正,使其正常工作。可以修改功能的签名。例如,"atoi" 将一个字符串作为输入。为达到与 non-extractive 相同的目的,简单创建一个可接受以下三个变量的“新 atoi”:(char* 类型的)源文档、(int 类型的)偏移和(int 类型的)长度。执行中的主要区别在于如何处理新字符串/标记表达(如:字符串的结尾不再标记为 \0)。
  • 裁减: 删除“non-extractive”标记字头及字尾空白空间只需要更改偏移和长度值。这通常比断词(tokenization)的抽取方式更简单,断词通常涉及新字符串的创建。
使用整数,而不是对象

一旦确定基于偏移/长度的断词(tokenization)可以运行,便会产生另一个问题:“标记必须是对象吗?”对象最基本的功能在于将多个成员变量/域绑定在一起。在面向对象的语言中,对象的概念还包括为访问控制和成员方法提供额外支持。然而,根据上文对 DOM 问题的论述,分配大量对象对性能和内存使用开销都会产生负面影响。因此,最好还是绕开对象。

幸运的是,目前存在一种简单的对象替代选择,可使用整数绑定多个变量。事实上,对象和整数的物理表达形式非常相似:它们都是位填充的小内存块。至于绑定部分,可以将所有位分成不同的组,表示不同的变量。例如,一个 32 位寄存器可以绑定四个 8 位整数、两个 16 位整数,甚至 32 个单位(single-bit)布尔值。要注意的是,这种整数的特殊用法在 X86 架构中非常普遍。例如,英特尔® 奔腾® 处理器中的各种网段寄存器和处理器状态寄存器都是 64 位,其中定制了许多子变量。

VTD-XML 基于称为虚拟标记描述符(VTD)的“non-extractive”二进制编码规范,在内部存储和表现 XML 的标记形式。VTD 记录是 64 位整数,对标记的起始偏移、长度、类型和嵌套深度进行 XML 编码。在数位分布层面,VTD 记录定义如下:

  • 起始偏移: 30位(b29 ~ b0)
  • 长度: 20位(b51 ~ b32)
  • 对某些标记类型来说:
    • 前缀长度: 9位(b51~ b43)
    • 合法名长度: 11位(b42 ~ b 32)
  • 嵌套深度: 8位(b59~b52), 最大值为2^8-2 = 254
  • 标记类型: 4位(b63~b60)
  • 保留位: 2位(b31: b30) 作为三态变量名称空间。
  • 单位: 由于处理模型没有对 XML 解码,因此偏移和长度的单位都是转化格式的原始字符。对于 UTF-8 和 ISO-8859,长度和偏移的单位是字节。对于 UTF-16 来说是 16 位字。图 1 描述了 VTD 记录的数位分布情况。
图 1. 基于网元目录的分级表达
在 DOM 中,一切都是节点(无论网元、文本、CDATA 或属性),内存中表达包括大量由指示器缝合起来的节点对象。把一切当作节点对象的例程会降低性能,同时增加内存使用开销。这是 DOM 处理速度缓慢的一个主要原因。试想:文本节点和属性节点都没有子节点,则把它们列入分级结构不仅会降低性能,而且也没有必要。

为了提供随机存取功能,VTD-XML 采取了使用位置缓存的基于网元的目录方法。位置缓存基本上类似于工作簿的索引部分,不同的是位置缓存是嵌套的目录。位置缓存只将网元(实际上是起始标记的 VTD 索引值)作为分级要素。位置缓存条目是一个 64 位整数,包含两个 32 位域:分别用于全球 VTD 索引和下一级位置缓存的相对索引。VTD-XML 的项目网站上提供了位置缓存的详尽描述以及 VTD 导航器的行为描述。


VTD-XML 如何解决 XML 的性能问题
高性能软件

在 Java 中实施时,VTD-XML 通过 NULL 内容处理程序实现 SAX 的性能等级,消耗的内存一般是在一个 XML 文档(大约一个 DOM 树的 1/3 到 1/5)尺寸的 1.3 和 1.5 倍之间。

为什么 VTD-XML 能够同时达到高性能与低内存使用呢?关键是减少了对象的创建。在许多基于虚拟机(VM)的 OOP 语言中,每一对象分配都会导致少量内存开销。VTD 记录不会受到此内存开销的影响,因为它们是整数而不是对象。另外,因为 VTD 记录的长度是不变的,所以它们能够被存到大内存块中,从而更有效地分配和 GC。例如,通过为 4096 VTD 记录分配一个大阵列,会导致每阵列的开销(在 JDK* 1.4 中为 16 字节),这样对每记录开销的减少是非常少的。至于性能,在对象分配与垃圾收集中占用较小内存意味成本更低。实际上,VTD-XML 的高性能是其有效内存使用的一个副产品。

定制硬件实施

随着更多 Web 服务应用通过网络交换 XML 信息,对于进行高速处理、过滤和保护信息的安全来说,网络工具变得越来越重要了。密切相关的主题是在芯片上移植 XML 处理。需要指出的是,VTD-XML 是被设计作为一个可以定制硬件实施的处理模型,能够实现千兆位性能等级。本文章对此没有进行深入的探讨,其基本思想是:VTD 使 XML 处理转变成为与 DES 加密密切相关的问题,DES 加密在定制硬件中实施时能够实现高性能。文章“在芯片上实现 XML”,详细讨论了该主题。

二进制增强型 XML

因为 VTD 和位置缓存基于 64 位整数,解析 XML 的 VTD-XML 的内部表述是持久稳固的,并可保存到磁盘或通过网络发送,以完全消除解析对资源的占用。换句话说,VTD 连同位置缓存与 XML 文档本身一起提供一个简单而有针对性的方式去索引 XML。更重要的是,索引 XML 不会导致 XML 内在优势的损失,比如可读性,以及 VTD-XML 保持 XML 在内存中的完整性。


VTD-XML 的其他优势
不断更新

考虑修改下列 XML 文件的文本内容。

<color> red </color>

使用 DOM,它至少需要以下三个步骤:建立 DOM 树,导航至文本节点并进行更新,然后将已更新的结构写入 XML。因此,无论修改是多么的微不足道,分析并来回编写文档都需要一个往返过程。如果一个大文档仅有一点细小的缺陷将会怎样?如果能像做手术般的去除它,然后将此更新插入到适当位置,那该多好啊!

VTD-XML 的非提取性断词(non-extractive tokenization)的直接优势是允许您正确完成它这操作。因为 VTD-XML 内部可保持 XML 文档的完整性和不被解码,并使用偏移/长度描述标记,因此不用重新串行化该文档的无关部分即可改变内容。例如,当把字节内容写入输出数据流时,通过由相应 VTD 记录指定的“空白”窗口,您可以删除一个标记。继续到下一步,您也可以通过使用该网元第一个和最后一个标记的 VTD 记录计算它的偏差和长度,从而一次清除整个网元。

内容抽取

同样,通过计算开始的偏移和长度,您可以处理 XML 文档的字节阵列中的一个元素,并将其从串行格式中剔除。使用该特性,您能够以前所未有的方式有效处理 XML 信息。例如,假设有两个用 VTD-XML 进行解析的 XML 文件。您可以从第一个文档中逐字地抽取片段,然后将其放到第二个文档的所需位置,它们仅占用很少的 CPU。实际上,VTD-XML 将更改和内容抽取转变成为字节缓冲处理操作。

易用性

意指 DOM 和 SAM 上的初期讨论,作为可建立一个内存中的可导航数据结构的 DOM 解析器,DOM 被认为更易于使用。但是,使用 DOM 的节点界面进行导航通常会引起不必要的混乱,因此开发人员必须确保进行大量节点测试和外在类型铸造。例如,它们并不试图获得子节点或无子节点,如属性节点。与 DOM 相比,因为 VTD-XML 表示 XML 的一个网元级,其导航更加简单有序,通常会使应用程度代码更简短。


结论
总而言之,解决 XML 的性能问题都是为了改进 XML 处理模块。本文介绍了 VTD-XML,它是一个全新的、开放源代码的 non-extractive XML 处理 API,不仅能解决现有处理模式的性能问题,还可提供许多新特性和优势。因为,通过采用优于传统方法的 XML 处理手段,并从第一步开始,VTD-XML 能够很好地实现其设计目的。当 XML 日益成为 IT 基础设施不可或缺的一部分时,VTD-XML 会应用到更多出色的 XML 应用中。
分享到:
评论

相关推荐

    经典XML处理实例采用DOM处理模式

    在XML文件读写中,DOM处理模式是一个常用的技术。它的工作原理是首先加载整个XML文件到内存,形成一个DOM树,然后通过遍历这棵树来查找、修改或添加数据。这种方式的好处在于能够方便地访问和修改任意位置的数据,但...

    有序的XML分支模式的高效处理

    在XML数据库中寻找所有分支模式(Twig Pattern)的有效方法成为了XML查询处理中的一个关键问题。当前的研究表明,整体分支连接算法(Holistic Twig Join)相比二元分解法具有明显的优势,因为它能更有效地控制中间...

    简化XML处理详解

    VTD-XML作为一种创新的XML处理模型,旨在解决上述问题。VTD-XML引入了非提取式标记化技术,将原始XML消息以二进制编码的虚拟标记描述符(VTD)形式存储,保留了XML的完整结构,同时减少了内存占用。VTD记录能够高效...

    SQL Server 2005中XML数据类型的性能

    在SQL Server 2005中,XML数据类型的性能优化是一项关键任务,因为XML在现代企业应用程序中扮演着越来越重要的角色,特别是在处理半结构化和非结构化数据时。SQL Server 2005引入了对XML的原生支持,允许XML数据存储...

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

    综上所述,VTD-XML通过其独特的非提取式解析模式解决了DOM和SAX中存在的效率瓶颈,不仅提高了XML处理的速度,而且降低了内存消耗,增强了易用性。随着XML技术在各行各业中的广泛应用,VTD-XML作为一种高效的XML处理...

    java实用工具包大众型XML处理

    Java实用工具包中的XML处理是Java开发者经常遇到的一项任务,特别是在处理数据交换、配置文件或者存储结构化数据时。XML(eXtensible Markup Language)因其结构清晰、可读性强的特点,被广泛应用。本工具包专门针对...

    一个C#版单例模式的xml解析类

    总结起来,这个C#版的单例模式XML解析类结合了单例设计模式和XML处理技术,为C#应用程序提供了一种高效且线程安全的方式来解析XML数据。使用`SingletonXmlParser`,开发人员可以在不担心实例化多个解析器的情况下,...

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

    接着,论文对现有的XML处理模式进行了分析,包括DOM和SAX。DOM将整个XML文档加载到内存中形成树形结构,适合小规模文档但不适用于大型XML;SAX是一种事件驱动的解析方式,只处理需要的部分,减少了内存消耗,但编程...

    kettle转换xml(XML Input Stream (StAX))

    这尤其适合处理大型XML文件,因为它避免了内存不足的问题。以下是如何在Kettle中设置和使用XML Input Stream (StAX) 转换步骤的步骤: 1. **创建转换**:在Kettle的 Spoon 工具中,新建一个转换,并添加“XML Input...

    vtd-xml XML解析工具

    它在XML处理领域中因其性能优异、内存占用低而受到广泛关注。"多快好省地建设社会主义"这句话虽然是一种比喻,但形象地表达了VTD-XML在处理XML文档时所追求的目标:快速、高效、节省资源。 VTD(Virtual Token ...

    XML递归模式的访问控制.doc

    综上所述,本文对XML递归模式的访问控制进行了深入研究,提出了创新的查询重写和递归节点处理算法,旨在增强XML数据的安全性,为XML访问控制提供更全面的解决方案。这些研究成果对于XML数据管理和网络安全领域具有...

    Oracle XML DB和DB2 pure XML在XML文档存储查询性能方面的比较分析.pdf

    DB2 pureXML将XML文档作为独立的对象存储,并且支持原生XML存储方式,避免了XML数据到关系模型的转换,从而提高了处理XML数据的性能。DB2 pureXML提供了XML索引和XML查询优化器,确保XML查询的高效执行。 在存储...

    人工智能-数据挖掘-基于数据挖掘技术的XML频繁模式发掘.pdf

    XML文档的模式抽取和数据存储是XML相关研究的核心问题,因为它们直接影响到XML的效率和功能的发挥。 数据挖掘技术是针对大量数据中隐藏知识的提取技术,它通过运用各种挖掘算法,揭示出对人们有用的信息。随着...

    Oracle XML DB 11g中 XML 数据管理

    ### Oracle XML DB 11g 中 XML 数据管理 #### 概述 ...通过合理的存储选择、模式注册、数据分割等策略,不仅能够有效应对数据管理的挑战,还能够充分发挥 Oracle XML DB 的性能优势,满足各种业务需求。

    XML的四种解析器原理及性能比较

    DOM4J不仅提供DOM和SAX两种解析方式,还支持XPath和XML Schema,且具备处理大文档的事件驱动模式。DOM4J的API设计得易于使用,且兼容DOM接口,使得在不同解析器间切换变得简单。 在选择解析器时,需要权衡性能、...

    as3写的拼图游戏,mvc模式开发,xml配置。

    本文将深入探讨基于ActionScript 3(AS3)编写的拼图游戏,该游戏采用Model-View-Controller(MVC)设计模式,并使用XML配置文件进行数据管理。这对于初学者理解MVC模式以及AS3在游戏开发中的应用极具价值。 首先,...

    ASP.NET处理XML

    同时,为了提高性能,有时会使用XML缓存策略来存储和重用频繁访问的XML内容。 总之,ASP.NET 提供了强大的工具来处理XML数据,无论是在Web服务中传输数据,还是在客户端页面上显示数据,都能轻松应对。理解和熟练...

    W3C XML Schema 模式的设计方法研究.pdfW3C XML Schema 模式的设计方法研究.pdf

    与关系数据库中的模式类似,XML Schema用特定的语言描述了XML文档的有效性规则,这些规则涵盖了元素、属性、数据类型等方面,使得文档能够按照预定的格式和语义被正确解析和处理。 #### 设计方法研究 W3C XML ...

    xmlvalue xml与C++数据结构的互相转换

    同时,要处理可能出现的错误,如无效的XML格式、缺少必要的元素或属性等。 5. **性能优化**:在大量数据转换时,性能是个关键因素。可能的优化策略包括使用SAX(Simple API for XML)解析器以减少内存占用,或者对...

Global site tag (gtag.js) - Google Analytics