以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 Java/Eclipse 』 (http://bbs.xml.org.cn/list.asp?boardid=41) ---- Java 中的 XML2 (http://bbs.xml.org.cn/dispbbs.asp?boardid=41&rootid=&id=8706) |
-- 作者:mfc42d -- 发布时间:7/9/2004 11:41:00 AM -- Java 中的 XML2 Java 中的 XML:数据绑定,第 2 部分:性能 英文原文 内容: 性能测试 输入计时 输出计时 内存使用情况 启动时间 那么什么是 JiBX 呢? 结束语 参考资料 关于作者 对本文的评价 相关内容: Data binding, part 1 Data binding with Castor XML document model performance in Java Understanding SAX Understanding DOM 在 XML 和 Web 服务专区还有: 教学 工具与产品 所有的文章 经过了第 1 部分对数据绑定框架的介绍后,现在对其进行测试 级别:中级 Dennis M. Sosnoski(dms@sosnoski.com) 企业 Java 专家 Dennis Sosnoski 研究了 Java 中用于 XML 数据绑定的几种框架的速度和内存使用情况。这些框架包含第 1 部分中讨论的所有代码生成方法、更早的一篇文章中讨论的 Castor 映射绑定方法和一种令人惊讶的有可能成功的新方法。如果您正在您的 Java 应用程序中使用 XML,那么您会希望了解如何将这些数据绑定方法结合在一起! 性能测试 清单 1. 紧凑的文档格式 注:清单 1 中的机场名称信息通常是一行代码。为了适应列大小,一些代码行被拆开,出现在两行上。 除了紧凑格式外,我还尝试了一个变体,它的数据值更多地使用了子元素(只对 ID 和 IDREF 继续使用属性)。下面是用在此被称为完整格式的格式表示的同一个数据: 清单 2. 完整的文档格式 通常,根据所用文档的大小不同,XML 框架的相对性能会有巨大差异,因此在这些性能测试中,我同时包含了大文档和小文档。大文档(time-comp.xml 和 time-full.xml)使用相同的数据值(分别以如上所示的两种不同格式表示)。因此大小明显不同(紧凑格式的为 106 KB,而完整格式的为 211 KB)。小文档都在集合中,每个集合包含 34 个文档,紧凑格式(ttcomp)的大小从 1.4-3.3 KB 不等,完整格式(ttfull)的大小从 2.2-5.8 KB 不等。与大文档一样,小文档集合中的相应文档包含相同的数据值。可以从下载页面(请参阅参考资料)获得测试中使用的完整文档集。 数据绑定字典 下面是我在本文中使用的一些术语的一个袖珍字典: 编组(Marshalling)是在内存中为对象生成 XML 表示的过程。与 Java 对象序列化一样,该表示需要包含所有从属对象:我们的主对象引用的那些对象,以及那些对象引用的对象等等。 数据分解(Unmarshalling)是编组的逆过程,它根据 XML 表示在内存中构建对象(可能还有一幅链接对象的图)。 映射(Mapping)是一组规则,用于显式地将对象编组到 XML 文档和根据 XML 文档分解对象。使用代码生成(基于文档的 DTD 或 W3C XML Schema 描述)的数据绑定方法通常包含隐式的映射,这些映射内置在已构造的对象中,因此在本文中,术语映射只用于将用户定义的 Java 对象与 XML 文档进行关联的方法。 所有测试结果都是使用 1.4GHz Athlon 系统(拥有 256MB DDR RAM,运行 RedHat Linux 7.2)获得的。在所有测试中,我都使用了 Sun 的 JDK 1.4.1 for Linux。所测试的每个数据绑定框架的特定版本如下:JAXB Beta 1、Castor 0.9.4.1、JBind 1.0 Beta 12/07、Quick 4.3.1 和 Zeus Beta 3.5(JiBX 是一个特例 — 请参阅测试结果后面的那么什么是 JiBX?以获取详细信息)。除了 JBind 和 JiBX 之外,所有测试都使用了 Piccolo SAX2 解析器 V1.0.3。这是我知道的最快的 SAX2 解析器,它通常可以达到或超出用于 JiBX 测试的 XMLPull 解析器(XPP3 V1.1.2)的速度。JBind 无法使用 Piccolo 解析器,因此为测试 JBind,我使用了 Xerces Java 2 V2.2.0。 为了提供数据绑定和其它备用方法之间的性能比较,我还只使用 SAX2 解析器对相同文件运行了计时测试,并且使用 dom4j 文档模型(文档模型中的性能佼佼者,它允许使用不同的 SAX2 解析器解析输入文档)运行了计时和内存测试。对于这些测试,我使用了 dom4j V1.3。 在这些计时和内存使用量测试中,我使用的基本框架与以前的文档模型测试(请在参考资料中参阅作者有关文档模型性能的文章。)中所用的相同。这个基准测试框架首先将所有文档读入内存缓冲区,然后对针对文档的输入和输出操作的多次传递进行计时。输入计时和输出计时中显示的测试结果是数次传递过程中的最佳计时。这应当代表了服务器类型的环境(其中重复执行相同的代码)中的长期性能。 输入计时 图 1. 将大文档读到内存中 相对于这些测试中的大多数绑定框架,JBind 的执行速度慢了整整一个数量级。这样拙劣的性能一小部分原因是由于用于 JBind 测试的解析器比较慢(因为它无法使用其它测试所用的解析器)。更大的原因可能是由于 JBind 强制在输入时对照 Schema 进行文档验证,这样会增加大量开销。但是,导致这一拙劣性能的最主要原因可能是由于 JBind 框架本身,该框架使用非常间接的方法来进行绑定(在当前实现中,绑定建立在 DOM 文档模型之上)。 除了 JBind 以外的所有测试都是在不进行完全验证的情况下运行的。大多数数据绑定框架仅按照其设计包含某个固有的验证级别(例如,确保元素的内容模型是匹配的)。大多数框架还可以使用验证解析器(如 Xerces Java 2)在输入时对文档进行完全检查,并且有框架(包括 JAXB)可以在内存中执行绑定数据的完全验证。因为在这些测试中主要关心的是性能,所以我尽可能地禁用了可选验证(包括在 Castor 中使用属性文件和数据分组程序/编组程序设置)。 输出计时 图 3. 从内存写大文档 内存使用情况 图 5. 大文档的内存使用情况 两种映射绑定方法为绑定数据使用了同一种内部结构,所以它们表现出了相同的内存使用情况。这让它们在内存效率的“竞技场”上并列第一,从而产生了比使用生成代码的数据绑定方法优越几倍的性能。部分原因是因为 映射绑定使用了数据值的紧凑表示。在这些测试中,映射绑定将大多数数据值转换成 int 值(在大多数 Java 虚拟机(Java Virtual Machine,JVM)中,String 即使只包含一个或两个字符,都将占用 20 个以上的字节,而 int 只占用 4 个字节)。该转换的开销增加了读写次数,但是除了只是内存大小减小了以外,它的确还有其它优点。当实际使用数据时,int 远比 String 更便利和有效。 映射绑定方法之所以能获得较高的内存效率,除了因为它更为广泛地使用了原语值外,另一个原因是生成代码方法通常会将控制信息添加到出现在每个绑定对象中的实际数据中去。该控制信息增加了对象的大小,因而数据绑定少了一个主要优点。 在这些测试中,使用生成代码的数据绑定框架消耗的内存至少是映射绑定的几倍,但是(除 JBind 外)仍然比 dom4j 的文档模型表示小很多。这一点不足为奇 — 诸如 dom4j 的文档模型需要构造一些对象以表示文档的每个组件(包括实际的数据文本以及诸如元素和属性之类的结构组件),而数据绑定只需要保存实际的数据。对于生成代码绑定而言,许多实际数据仍然是作为 String 存储的,但是一些值可以被转换成 int,而其它值可被转换成对象引用。 这里,Zeus 被认为是唯一直接将所有数据存储为 String 的数据绑定方法,这使它成为常用的数据绑定方法中占用内存最大的一种方法。到目前为止,JBind 的内存使用情况仍然较大。这有一部分是由于它在内部使用了文档模型,但是 JBind 使用的内存量要比单独使用文档模型(如 dom4j)所需的内存量大好几倍。从该内存使用情况判断,似乎 JBind 创建了许多其它对象,以建立绑定虚包(facade)和文档模型中实际数据之间的链接。 启动时间 图 7. 启动时间 数据绑定框架使用的 jar 文件的大小是影响这一启动时间的一个主要因素。JiBX 是最小的,运行时和解析器的总大小不足 60KB。JAXB、Castor 和 JBind 是最大的,每个大小大约为 1MB。该时间还受每个框架所需的初始化影响。在使用映射绑定的 Castor 情形中,该时间包含处理映射定义文件,而对于 JBind 而言,它包含处理文档的 Schema 定义。 那么什么是 JiBX 呢? JiBX 实际上源于本系列文章。当我开始研究可用的数据绑定框架时,我惊奇地看到:与文档模型(如 dom4j)相比,它们并不是执行得都那样好。这与我的期望相反,因为数据绑定方法实际上减少了保存在内存中的文档信息的数量 — 而文档模型在内存中保存所有事物,同时数据绑定只需要实际数据。我认为,数据用得少的方法通常应该比那些数据用得多的方法要快。 在研究现有数据绑定框架是如何操作的过程中,我发现从性能角度来说有两个方面看上去不是很好。第一个方面就是许多框架中广泛使用了反射。反射是在运行时访问有关 Java 语言类的信息的一种方法。可用它来访问类实例中的字段和方法,从而提供了一种在运行时将类动态地挂钩在一起,却无需类之间有任何源代码链接的方法。反射是一种功能非常强大的 Java 技术特性,但是将其与调用方法或直接访问已编译代码中的字段相比,它在性能上有些欠缺。 我质疑的第二个方面是使用 SAX2 解析器对文档进行数据分解。SAX2 是一种非常有用的解析 XML 的标准,但是其事件驱动方法并不非常适合数据绑定和类似的应用程序。这里的问题在于,处理 SAX2 事件的代码需要维护其处理的所有事情的状态信息,这既增加了复杂性又增加了开销。 我创建了形成 JiBX 的代码,以对一些方法(解决其它数据绑定框架中所存在的这些问题)进行测试,并实验扩展超出 Castor 支持范围的映射绑定方法。JiBX 使用字节代码增强而不是反射来在项目构建时将挂钩添加进应用程序代码。JiBX 基于拉(pull)解析器体系结构(当前是 XMLPull),而不是 SAX2。JiBX 不是根据 DTD 或 Schema 生成代码,而是使用绑定定义,该定义将用户提供的类与 XML 结构相关联。 这些技术并不是 JiBX 所特有的。许多 Java 数据对象(Java Data Object,JDO)实现都使用字节代码增强,基本上都是为了达到与 JiBX 相同的目的(将访问挂钩添加到现有的已编译代码中)。原始的 JAXB 代码(已被丢弃)基于类似 XMLPull 的拉解析器体系结构。Castor 和 Quick 都支持数据绑定的映射方法(尽管有一些限制)。即使个别技术不是很新,但是它们的组合仍然可以形成其它数据绑定框架非常有趣的备用方案。 在本系列文章的第 3 部分,我将完整地介绍有关 JiBX 的知识。JiBX 仍然处于初期开发阶段。为了性能测试,我手工编写了代码,通常通过字节代码增强添加该代码,并使用 JiBX 运行时的当时版本来运行它。到本文发表时,我仍在着手完成增强代码,有许多其它特性我希望添加到其中。如果您在第 3 部分发表前就希望了解更多有关 JiBX 的知识,请查阅参考资料以获取到 JiBX 站点的链接。您甚至可以为 JiBX 的未来开发献策献力,也可以在您自己的应用程序中使用 JiBX。 结束语 JAXB 看上去将来仍是代码生成方法的一个不错选择(测试版许可证只允许评估使用)。当前的参考实现测试版在 jar 大小方面非常庞大,并且在内存使用方面的效率也略嫌不足,但是这里再重申一次,将来您可能会看到更佳的性能。在撰写本文的时候,当前版本仍然是测试版,只有当它作为商业或开放源码项目发布以后,它的性能才可能优于参考实现。由于它将作为 J2EE 平台的标准部分,所以关于在 Java 中使用 XML 方面,JAXB 无疑会扮演重要的角色。 性能结果也证实:JBind、Quick 和 Zeus 最适用于有特殊需求的应用程序,而不应该用于一般用途。JBind 的 XML 代码方法可以为围绕 XML 文档处理而构建的应用程序提供重要基础,但是当前实现的性能容易导致问题。Quick 和 Zeus 提供根据 DTD 进行代码生成,但是正如我在第 1 部分中提到的那样,将 DTD 转换成 Schema 通常相当简单。缺点是,Quick 使用起来似乎过于复杂,而 Zeus 只支持 String 用于绑定数据值(没有原语或使用 ID-IDREF 或等价物的对象引用)。 对于数据绑定的映射方法,Castor 的优点是:它是一个相当稳定的实现,并可投入实际使用。Quick 也可以用于这类的绑定,但是似乎也难于设置。JiBX 是新事物,并且尚未完全投入使用,但是它提供了卓越的性能和高度的灵活性。 如果您还未阅读第 1 部分,您也许应该回头阅读一下那篇文章,以便了解更多有关这些数据绑定框架特性的知识。第 1 部分还讨论了数据绑定的代码生成和映射方法之间的权衡。在第 3 部分中,我将深入介绍新的 JiBX 框架。这包括 JiBX 如何将 Java 对象映射到 XML,以及 JiBX 为最小化运行时开销而在构建时使用的字节代码增强过程。请回来查看有关这个令人振奋的方法的完整信息,以提升框架性能! 参考资料 参与有关本文的论坛。(您也可以通过单击文章顶部或底部的讨论来访问论坛。) 关于作者 |
-- 作者:xmzhy -- 发布时间:4/2/2005 9:39:00 AM -- 有道理 |
-- 作者:lqefn -- 发布时间:4/22/2005 5:33:00 PM -- good |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
250.000ms |