实现高性能Java解析器

备注: 本篇文章是关于先前相同主题文章的最新版本。先前文章主要介绍创建高性能解析器的一些要点,但它吸收了读者的一部分批评建议。原来的文章进行了全面修订,并补充了相对完整的代码。我们希望你喜欢本次更新。

如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器。或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能。或者开源解析器存在缺陷,或者开源解析器项目被取消诸如此类原因。上述原因都没有你将需要实现你自己的解析器的事实重要。

当你必需实现自己的解析器时,你会希望它有良好表现,灵活,功能丰富,易于使用,最后但更重要是易于实现,毕竟你的名字会出现在代码中。本文中,我将介绍一种用Java实现高性能解析器的方式。该方法不具排他性,它是简约的,并实现了高性能和合理的模块化设计。该设计灵感来源于VTD-XML ,我所见到的最快的java XML解析器,比StAX和SAX Java标准XML解析器更快。

两个基本解析器类型

解析器有多种分类方式。在这里,我只比较两个基本解析器类型的区别:

顺序访问解析器(Sequential access parser)

随机访问解析器(Random access parser)

顺序访问意思是解析器解析数据,解析完毕后将解析数据移交给数据处理器。数据处理器只访问当前已解析过的数据;它不能回头处理先前的数据和处理前面的数据。顺序访问解析器已经很常见,甚至作为基准解析器,SAX和StAX解析器就是最知名的例子。

随机访问解析器是可以在已解析的数据上或让数据处理代码向前和向后(随机访问)。随机访问解析器例子见XML DOM解析器。

顺序访问解析器只能让你在文档流中访问刚解析过的“窗口”或“事件”,而随机访问解析器允许你按照想要的方式访问遍历。

设计概要

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

随机访问解析器实现总是比顺序访问解析器慢一些,这是因为它们一般建立在某种已解析数据对象树上,数据处理器能访问上述数据。创建对象树实际上在CPU时钟上是慢的,并且耗费大量内存。

代替在解析数据上构建对象树,更高性能的方式是建立指向原始数据缓存的索引缓存。索引指向已解析数据的元素起始点和终点。代替通过对象树访问数据,数据处理代码直接在含有原始数据的缓存中访问已解析数据。如下是两种方法的示意图:

因为没找到更好的名字,我就叫该解析器为“索引叠加解析器”。该解析器在原始数据上新建了一个索引叠加层。这个让人想起数据库构建存储在硬盘上的数据索引的方式。它在原始未处理的数据上创建了指针,让浏览和搜索数据更快。

如前所说,该设计受VTD-XML的启发, VTD是虚拟令牌描述符(Virtual Token Descriptor)的英文缩写。因此,你可以叫它虚拟令牌描述符解析器。不过,我更喜欢索引叠加的命名,因为这是虚拟令牌描述符代表,在原始数据上的索引。

时间: 2025-01-13 22:49:24

实现高性能Java解析器的相关文章

Java ReStructuredText 1.4发布 Java解析器和转换器

reStructuredText是一个Java解析器和转换器.用于解析reStructuredText和生成XHTML,xdoc和DocBook文件,或可以使用自己的XSL文件. Java ReStructuredText 1.4版本添加了联机图像放到account的新功能,修复了多个错误. 下载地址: http://www.nuiton.org/attachments/download/518/jrst-1.4-deps.zip http://www.nuiton.org/attachment

实现Java中的高性能解析器

在某些情况下,你可能需要在Java中实现你自己的数据或语言解析器,也许是这种数据格式或语言缺乏标准的Java或开源解析器可以使用.或者虽然有现成的解析器实现,但它们要么太慢,要么太占内存,要么就是没有符合你所需要的特性.又或者是某个开源的解析器存在缺陷,要么是某个开源解析器的项目中止了,原因不一而足.不过无论原因是什么,总之事实就是你必须要自己去实现这个解析器. 当你必须自己实现一个解析器时,你对它的期望会有很多,包括性能良好.灵活.特性丰富.方便使用,以及便于维护等等.说到底,这也是你自己的代

利用Java实现组合式解析器

简介:Ward Cunningham 曾经说过,干净的代码清晰地表达了代码编写者所 想要表达的东西,而优美的代码则更进一步,优美的代码看起来就像是专门为了 要解决的问题而存在的.在本文中,我们将展示一个组合式解析器的设计.实现 过程,最终的代码是优美的,极具扩展性,就像是为了解析特定的语法而存在的 .我们还会选取 H.248 协议中的一个例子,用上述的组合式解析器实现其语法 解析器.读者在这个过程中不仅能体会到代码的美感,还可以学习到函数式编程 以及构建 DSL 的一些知识. DSL 设计基础

jsoup v1.6.0发布 一款Java的HTML解析器

jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据.其他方面的改进请看发行说明. jsoup 1.6.0发行说明: jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulati

《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一3.6.1 使用SAX解析器

3.6.1 使用SAX解析器 SAX解析器在解析XML输入数据的各个组成部分时会报告事件,但不会以任何方式存储文档,而是由事件处理器建立相应的数据结构.实际上,DOM解析器是在SAX解析器的基础上构建的,它在接收到解析器事件时构建DOM树. 在使用SAX解析器时,需要一个处理器来为各种解析器事件定义事件动作.ContentHandler接口定义了若干个在解析文档时解析器会调用的回调方法.下面是最重要的几个: startElement和endElement在每当遇到起始或终止标签时调用. char

groovy/java自实现json解析器(1)绪论

groovy是一门以java为基础的动态语言,它强大地动态特性为我们的敏捷开发带来了极大的便利,下面是一个由grovvy(完美兼容嵌套java实现的json)解析器的部分代码展示,我们都知道,json字符串只要满足格式要求,那么它是可以无限循环嵌套的,而本解析器的核心实现就是大量的递归函数运用,将json字符串一层层地解析开,并拼装成我们相应的数组或对象.它主要由以下五个类组成: --JsonObject.groovy --JsonArray.groovy --JsonTool.groovy -

groovy/java自实现json解析器(2)JsonObject

底层数据结构实现 本对象的底层数据结构是一个Map(映射),我们用def private jsonMap将其定义为对象变量.我们在构造函数中对其进行初始化,它以键值对的形式存储数据,其中键必须为字符串,值可以为字符串.Boolean.Integer.JsonArray.JsonObject,从最后两个可存储对象,我们或多或少地已能看出JsonObject是如何达成普通json对象里的无限嵌套了. 下面是本对象的构造函数. def JsonObject( jsonMap = null) { thi

《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一3.6.2 使用StAX解析器

3.6.2 使用StAX解析器 StAX解析器是一种"拉解析器(pull parser)",与安装事件处理器不同,你只需使用下面这样的基本循环来迭代所有的事件: 解析器将产生下面的事件: 1)START_ELEMENT,元素名:font 2)CHARACTERS,内容:空白字符 3)START_ELEMENT,元素名:name 4)CHARACTERS,内容:Helvetica 5)END_ELEMENT,元素名:name 6)CHARACTERS,内容:空白字符 7)START_EL

jsoup v1.5.2发布 一款Java的HTML解析器

jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址.HTML文本内容.比起之前用的HTMLhttp://www.aliyun.com/zixun/aggregation/33959.html">Parser方便很多,而且更轻便.语法类似jquery. 它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据. This is a minor release, that primarily corrects a regress