这篇文章探讨了使用多种不同方法将XML文档编组为Java对象的性能。 XML文档非常简单。 它包含一个Person实体的集合。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persons><person><id>person0</id><name>name0</name></person><person><id>person1</id><name>name1</name></person>
...

XML中的Person实体有一个对应的Person Java对象
..

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"id","name"
})
public class Person {private String id;private String name;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String value) {this.name = value;}
}

和一个PersonList对象代表一个Persons集合。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "persons")
public class PersonList {@XmlElement(name="person")private List<person> personList = new ArrayList<person>();public List<person> getPersons() {return personList;}public void setPersons(List<person> persons) {this.personList = persons;}
}

研究的方法是:

  • 各种口味的JAXB
  • 萨克斯
  • DOM
在所有情况下,目标都是使XML文档中的实体到达相应的Java对象。 在Person和PersonList POJOS上的JAXB批注用于JAXB测试中。 可以在SAX和DOM测试中使用相同的类(注释将被忽略)。 最初是参考

使用了JAXB,SAX和DOM的实现。 然后使用Woodstox STAX解析。 在某些JAXB解组测试中会调用此方法。

测试是在运行Windows 7的戴尔笔记本电脑,2.1 GHz奔腾双核CPU上进行的。

测试1 –使用JAXB解组Java文件。

@Test
public void testUnMarshallUsingJAXB() throws Exception {JAXBContext jc = JAXBContext.newInstance(PersonList.class);Unmarshaller unmarshaller = jc.createUnmarshaller();PersonList obj = (PersonList)unmarshaller.unmarshal(new File(filename));
}

测试1说明了JAXB的编程模型有多简单。 从XML文件到Java对象非常容易。 无需参与编组和解析的精妙细节。

测试2 –使用JAXB解组流源


测试2与测试1类似,不同之处在于,这次流源对象包装在文件对象周围。 Streamsource对象向JAXB实现提供提示以流式传输文件。

@Test
public void testUnMarshallUsingJAXBStreamSource() throws Exception {JAXBContext jc = JAXBContext.newInstance(PersonList.class);Unmarshaller unmarshaller = jc.createUnmarshaller();StreamSource source = new StreamSource(new File(filename));PersonList obj = (PersonList)unmarshaller.unmarshal(source);
}

测试3 –使用JAXB解组StAX XMLStreamReader

再次类似于测试1,除了这次XMLStreamReader实例包装了由JAXB编组的FileReader实例。

@Test
public void testUnMarshallingWithStAX() throws Exception {FileReader fr = new FileReader(filename);JAXBContext jc = JAXBContext.newInstance(PersonList.class);Unmarshaller unmarshaller = jc.createUnmarshaller();XMLInputFactory xmlif = XMLInputFactory.newInstance();XMLStreamReader xmler = xmlif.createXMLStreamReader(fr);PersonList obj = (PersonList)unmarshaller.unmarshal(xmler);
}

测试4 –仅使用DOM

该测试不使用JAXB,而是仅使用JAXP DOM方法。 这意味着比任何JAXB方法都需要更多的代码。

@Test
public void testParsingWithDom() throws Exception {DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = domFactory.newDocumentBuilder();Document doc = builder.parse(filename);List personsAsList = new ArrayList();NodeList persons = doc.getElementsByTagName("persons");for (int i = 0; i <persons.getLength(); i++) {Element person = (Element)persons.item(i);NodeList children = (NodeList)person.getChildNodes();Person newperson = new Person();for (int j = 0; j < children.getLength(); j++){Node child = children.item(i);if (child.getNodeName().equalsIgnoreCase("id")) {newperson.setId(child.getNodeValue());} else if (child.getNodeName().equalsIgnoreCase("name")) {newperson.setName(child.getNodeValue());}}personsAsList.add(newperson);}
}

测试5 –仅使用SAX测试5不使用JAXB,而使用SAX来解析XML文档。 与任何JAXB方法相比,SAX方法涉及更多的代码和更多的复杂性。 开发人员必须参与文档的解析。

@Test
public void testParsingWithSAX() throws Exception {SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser saxParser = factory.newSAXParser();final List<person> persons = new ArrayList<person>();DefaultHandler handler = new DefaultHandler() {boolean bpersonId = false;boolean bpersonName = false;public void startElement(String uri, String localName,String qName,    Attributes attributes) throws SAXException {if (qName.equalsIgnoreCase("id")) {bpersonId = true;Person person = new Person();persons.add(person);} else if (qName.equalsIgnoreCase("name")) {bpersonName = true;}}public void endElement(String uri, String localName, String qName) throws SAXException {}public void characters(char ch[], int start, int length) throws SAXException {if (bpersonId) {String personID = new String(ch, start, length);bpersonId = false;Person person = persons.get(persons.size() - 1);person.setId(personID);} else if (bpersonName) {String name = new String(ch, start, length);bpersonName = false;Person person = persons.get(persons.size() - 1);person.setName(name);}}};saxParser.parse(filename, handler);
}

对于包含Person实体集合的3个文件,该测试运行了5次。 第一个文件包含100个Person实体,大小为5K。 第二个包含10,000个实体,大小为500K,第三个包含250,000个Person实体,大小为15 Meg。 在任何情况下都不会使用任何XSD或进行任何验证。 结果在结果表中给出,其中不同运行时间用逗号分隔。

试验结果

首先使用32位JDK 1.6.26运行测试,并使用JDK附带的SAX,DOM和JAXB的参考实现。

解组类型 100人次(毫秒) 10K人次(毫秒) 25万人次(毫秒)
JAXB(默认) 48,13,5,4,4 78,52,47,50,50 1522、1457、1353、1308、1317
JAXB(流源) 11,6,3,3,2 44,44,48,45,43 1191、1364、1144、1142、1136
JAXB(StAX) 18,2,1,1,1 111、136、89、91、92 2693、3058、2495、2472、2481
DOM 16,2,2,2,2 89,50,55,53,50 1992、2198、1845、1776、1773
萨克斯 4,2,1,1,1 29,34,23,26,26 704、669、605、589,591



JDK 1.6.26测试注释

  1. 通常,第一次进行编组的时间最长。
  2. JAXB和SAX的内存使用情况相似。 10,000个人的档案约为2 Meg,而250,000的档案是36 – 38 Meg档案。 DOM内存使用率更高。 对于10,000个人档案,它是6 Meg,对于250,000个人档案,它是大于130 Meg。
  3. 纯SAX的性能更好。 特别是对于非常大的文件。

使用相同的JDK(1.6.26)再次运行完全相同的测试,但是这次使用了StAX解析的Woodstox实现。

解组类型 100人次(毫秒) 10K人次(毫秒) 25万人次(毫秒)
JAXB(默认) 168,3,5,8,3 294、43、46、43、42 2055、1354、1328、1319、1319
JAXB(流源) 11,3,3,3,4 43,42,47,44,42 1147、1149、1176、1173、1159
JAXB(StAX) 30,0,1,1,0 67,37,40,37,37 1301、1236、1223、1336、1297
DOM 103,1,1,1,2 136,52,49,49,50 1882、1883、1821、1835、1822
萨克斯 4,2,2,1,1 31,25,25,38,25 613、609、607、595、613



JDK 1.6.26 + Woodstox测试注释

  1. 同样,第一次进行编组通常会成比例地变长。
  2. 同样,SAX和JAXB的内存使用情况非常相似。 两者都好得多

    比DOM。 结果与测试1非常相似。

  3. JAXB(StAX)进近时间已大大缩短。 这是由于

    正在使用StAX解析的Woodstox实现。

  4. 纯SAX的性能时间仍然是最好的。 尤其

    用于大文件。

再次运行完全相同的测试,但是这次我使用了JDK 1.7.02和StAX解析的Woodstox实现。

解组类型 100人次(毫秒) 10,000人次(毫秒) 250,000人次(毫秒)
JAXB(默认) 165,5,3,3,5 611,23,24,46,28 578、539、511、511、519
JAXB(流源) 13,4,3,4,3 43,24,21,26,22 678、520、509、504、627
JAXB(StAX) 21,1,0,0,0 300,69,20,16,16 637、487、422、435、458
DOM 22,2,2,2,2 420,25,24,23,24 1304、807、867、747、1189
萨克斯 7,2,2,1,1 169,15,15,19,14 366、364、363、360、358



JDK 7 + Woodstox测试注释:

  1. 总体而言,JDK 7的性能要好得多。 有一些异常-第一次解析100个人和10,000个人档案。
  2. 内存使用量略高。 对于SAX和JAXB,10,000人档案为2 – 4 Meg,对于250,000人档案为45 – 49 Meg。 对于DOM,它再次更高。 10,000人的档案5 – 7.5 Meg,250,000人的档案136 – 143 Meg。



注意:WRT所有测试

  1. 没有对100人文件进行内存分析。 内存使用量太小,因此将没有意义的信息。
  2. 首次初始化JAXB上下文最多需要0.5秒。 这不包括在测试结果中,因为这只是第一次。 之后,JVM会非常快地初始化上下文(始终小于5毫秒)。 如果您在使用任何JAXB实现时都注意到此行为,请考虑在启动时进行初始化。
  3. 这些测试是一个非常简单的XML文件。 实际上,将会有更多的对象类型和更复杂的XML。 但是,这些测试仍应提供指导。

结论:

  1. 纯SAX的性能时间略好于JAXB,但仅适用于非常大的文件。 除非使用的文件非常大,否则性能差异不值得担心。 JAXB的编程模型优势克服了SAX编程模型的复杂性。 别忘了JAXB也像DOM一样提供随机访问。 SAX不提供此功能。
  2. 如果使用JAXB / StAX,则使用Woodstox的性能时间看起来要好得多。
  3. 使用64位JDK 7的性能看起来要好得多。 内存使用情况看起来略高。

参考:来自都柏林技术博客的 JCG合作伙伴 Alex Staveley的JAXB,SAX,DOM性能 。

相关文章 :

  • 使用JAXB从XSD生成XML
  • 将对象映射到多个XML模式–天气示例
  • 使用Spring MVC开发Restful Web服务
  • 具有简单框架教程的Android XML绑定
  • 使用XML Pull增强Android XML解析

翻译自: https://www.javacodegeeks.com/2011/12/jaxb-sax-dom-performance.html

JAXB,SAX,DOM性能相关推荐

  1. dom4j和jaxb_JAXB,SAX,DOM性能

    dom4j和jaxb 这篇文章研究了使用多种不同方法将XML文档编组为Java对象的性能. XML文档非常简单. 它包含一个Person实体的集合. <?xml version="1. ...

  2. 浅析SAX,DOM,JAXP,JDOM与DOM4J之间的关系

    转载自   浅析SAX,DOM,JAXP,JDOM与DOM4J之间的关系 众所周知,SAX与DOM是JAVA中两大核心XML解析API类库,而JAXP,JDOM与DOM4J都是基于这两大核心API而衍 ...

  3. Java XML分析技术: StAX, SAX, DOM, DOM4j, JDOM

    Java 6.0对XML支持的新特性有许多方面.比如StAX.针对XML-Web服务的Java架构(JAX-WS)2.0.针对XML绑定的API(JAXB)2.0.XML数字签名API,甚至还支持SQ ...

  4. 10. 解析XML文件(SAX/DOM/ElementTre)

    XML的全称是eXtensible Markup Language, 意为可扩展的标记语言, 是一种用于标记电子文件使其具有结构性的标记语言.以XML结构存储数据的文件就是XML文件,它被设计用来传输 ...

  5. xml解析:Sax,Dom,pull解析

    Sax 1.startDocument()文档开始 2.endDocument()文档结束 3.startElement(String namespaceURI,String localName,St ...

  6. sax dom html解析xml,Python通过DOM和SAX方式解析XML的应用实例分享

    XML.DOM 需求 有一个表,里面数据量比较大,每天一更新,其字段可以通过xml配置文件进行配置,即,可能每次建表的字段不一样. 上游跑时会根据配置从源文件中提取,到入库这一步需要根据配置进行建表. ...

  7. Java解析xml的主要解析器: SAX和DOM的选择(附上新方法--Pull解析)

    Java的xml解析器库有很多,总的来说,万变不离其宗的就是SAX和DOM解析器. SAX的包是org.xml.sax DOM的包是org.w3c.dom 1) DOM DOM 是用与平台和语言无关的 ...

  8. DOM解析和SAX解析的区别

    DOM解析和SAX解析的区别 博客分类: XML DOM SAX  DOM解析和SAX解析的区别 No 区 别 DOM解析 SAX解析 1 操作 将所有文件读取到内存中形成DOM树,如果文件量过大,则 ...

  9. stax 和jaxb 关系_XML解组基准:JAXB,STAx,Woodstox

    stax 和jaxb 关系 介绍 上周末,我开始考虑如何以一种资源友好的方式处理大量XML数据.我要解决的主要问题是如何以块的形式处理大型XML文件,同时提供上游/下游系统,需要处理一些数据. 当然, ...

最新文章

  1. linux指令 2>1 到底是个啥
  2. java日记(2)------定时任务quartz浅析
  3. 【C#学习笔记】退出程序
  4. 每日一皮:强大的sudo ...
  5. 搭建EJB3开发环境
  6. 阿里云自营建站买一年送一年
  7. SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析
  8. python图像增强_Python图像的增强处理操作示例【基于ImageEnhance类】
  9. N进制的规范十进制表示(洛谷P2084题题解,Java语言描述)
  10. 基础编程题之二进制插入(位运算)
  11. 基于51单片机的数码管显示方案
  12. 【Redis】Redis配置文件详解
  13. 餐厅点菜c语言程序代码,餐馆点菜系统C语言源代码.pdf
  14. spring入参为指定值,校验java入参的值为规定的值,利用Validator指定值校验注解——一看就会
  15. [无线玩家]玩转无线路由之DD-WRT基础扫盲
  16. win7下批处理bat文件:切换网络设置
  17. 设备驱动程序是什么?为什么要有设备驱动程序?用户进程怎样使用驱动程序?
  18. zbb20181224 win7 下的open live writer代码插件
  19. 借助花生壳使用公网远程连接Jetson nano
  20. 看似简单的任务-分享二维码图片到微信(分享图片的生成)

热门文章

  1. 缓存与数据库的一致性:先操作缓存还是先操作数据库?
  2. HDU1231(最大连续子序列)
  3. java jvm虚拟机_Java虚拟机(JVM)简介
  4. javaone_JavaOne 2015:为JDK 9做准备– blog @ CodeFX
  5. java java se_Java 8 SE可选,严格的方法
  6. sap寄售退货单_多个退货单
  7. 带有HttpClient的自定义HTTP标头
  8. 功能Java示例 第8部分–更多纯函数
  9. javafx html5_JavaFX技巧5:可观察
  10. jit 和 jvm_关于JVM和JIT的一点点