微信号:infoqchina

介绍:有内容的技术社区媒体

实现Java中的高性能解析器

2014-01-13 23:12 InfoQ

在某些情况下,你可能需要在Java中实现自己的数据或语言解析器,也许是这种数据格式或语言缺乏标准的Java或开源解析器可供使用。或者虽然有现成的解析器实现,但要么太慢,要么太占内存,要么就是没有所需的特性。又或者是某个开源的解析器存在缺陷,要么是某个开源解析器的项目中止了,原因不一而足。不过无论原因是什么,总之事实就是必须自己去实现这个解析器。


当你必须自己实现一个解析器时,你对它的期望会有很多,包括性能良好、灵活、特性丰富、方便使用,以及便于维护等等。说到底,这也是你自己的代码。在本文中,我将为你介绍在Java中实现高性能解析器的一种方式,这种方并不是唯一的方案,但难度适中,不仅实现了高性能,而且它的模块化设计方式也比较合理。这种设计是受到了VTD-XML的设计方式的启发,后者是我所见过的最快的Java XML解析器,比起StAX和SAX这两种标准的Java XML解析器都要快上许多。


两种基本的解析器类型


为解析器进行分类的方式有好几种,在这里我将解析器分为两种基础类型:

  • 顺序访问解析器

  • 随机访问解析器


顺序访问是指解析器对进行数据进行解析,在数据解析完成后将其转交给数据处理器(processor)的过程。数据处理器只能访问当前正在进行解析的数据,它既不能访问已解析过的数据,也不能访问等待解析的数据。这种解析器也被称为基于事件的解析器,例如SAX和StAX解析器。


而随机访问解析器是指解析器允许数据处理代码可以随意访问正在进行解析的数据之前和之后的任意数据(随机访问)。这种解析器的例子有XML DOM解析器。


下图展示了顺序访问解析器与随机访问解析器的不同之处:


顺序访问解析器只能让你访问当前正在解析的“视窗”或“事件”,而随机访问解析器允许你任意地浏览所有已解析数据。


设计概况


我在这里所介绍的解析器设计属于随机访问解析器。


随机访问解析器的实现通常会慢于顺序访问解析器,因为它们一般都会为已解析数据创建某种对象树,数据处理代码将通过这棵树对数据进行访问。创建这种对象树不仅要花费较长的CPU时间,消耗的内存也很大。


相对于从已解析数据中创建一棵对象树的方式,另一种性能更佳的方式是为原来的数据缓冲区建立一个对应的索引缓冲区,这些索引会指向在已解析数据中找到的元素的起点与终点。数据处理代码此时不再通过对象树访问数据,而是直接在包括了原始数据的缓冲区中访问已解析数据。以下是对这两种处理方式的图示:


 

本文将带领大家一步一步实现一个高性能解析器。更多精彩内容,请点击阅读原文。


***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿和加入编辑团队的流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 第一部分::任务4:搭建数据库&程序同数据库连接 2016.07成长记录 第一个C语言编译器是怎样编写的? 一个高端.NET技术人才的年度总结 别BiBi了!用大数据解读《你正常吗》进化论