前言:
  之前在查阅jaxb相关资料的同时, 也看到了一些关于性能优化的点. 主要集中于对象和xml互转的过程中, 确实有些实实在在需要注意的点. 这边浅谈jaxb性能优化的一个思路.

案列:
  先来构造一个简单的例子:

    @Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement(name="txn")
@XmlAccessorType(XmlAccessType.FIELD)
public static class TNode { @XmlElement(name="key", required = true)
private String key; @XmlElement(name="value", required = true)
private String value; }

  注: 这个基本的映射对象类

	public static <T> String writeAsString(T t) {
try {
JAXBContext jc = JAXBContext.newInstance(t.getClass());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); StringWriter writer = new StringWriter();
marshaller.marshal(t, writer);
return writer.toString();
} catch (JAXBException ex) {
ex.printStackTrace();
}
return null;
}

  注: 这是最经典的java对象转化为xml的代码片段.

    @Test
public void testPref() { TNode node = new TNode("key", "value"); // *) 迭代重复的次数
int numIter = 1000;
long startTime = System.currentTimeMillis();
for ( int i = 0; i < numIter; i++ ) {
writeAsString(node);
}
long endTime = System.currentTimeMillis(); System.out.println(String.format("iter num: %d, consume: %dms, avg: %.2fms",
numIter, (endTime - startTime), (endTime - startTime) * 1.0 / numIter)); }

  注: 这是实际执行的性能评估代码, 注意这边的迭代次数.

  测试一下在迭代100/1000/10000次的, 总耗时及平均耗时.

iter num: 100, consume: 2001ms, avg: 20.01ms
iter num: 1000, consume: 11020ms, avg: 11.02ms
iter num: 10000, consume: 108290ms, avg: 10.83ms

  大致维持在10ms, 这算一个比较酸涩的结果, 如果映射是个复杂的对象, 其耗时会成倍的增加, 对于追求高并发低延时的互联网应用而言, 略显尴尬, redis平均为1ms, mysql/mongo基本维持在10ms范围内. 因此jaxb虽然非常好用, 但是性能需要优化.

瓶颈定位&优化:
  经过测试, 基本聚焦在JAXBContext.newInstance这个方法中. 其生成的JAXBContext实例代价高, 但其是无状态(线程安全), 我们可以想到的一个优化措施是缓存.
  对转换代码做下小改动:

private static ConcurrentHashMap<Class, JAXBContext> jaxbContMap
= new ConcurrentHashMap<Class, JAXBContext>(); public static <T> String writeAsString(T t) {
try {
JAXBContext jc = jaxbContMap.get(t.getClass());
if ( jc == null ) {
synchronized (t.getClass()) {
jc = JAXBContext.newInstance(t.getClass());
jaxbContMap.put(t.getClass(), jc);
}
}
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); StringWriter writer = new StringWriter();
marshaller.marshal(t, writer);
return writer.toString();
} catch (JAXBException ex) {
ex.printStackTrace();
}
return null;
}

  注: 引入ConcurrentHashMap来缓存类类型到具体的JAXBContext实例.
  再测试100/1000/10000调用次数的平均时耗, 结果如下:

    iter num: 100, consume: 295ms, avg: 2.95ms
iter num: 1000, consume: 1325ms, avg: 1.33ms
iter num: 10000, consume: 5688ms, avg: 0.57ms

  结果非常令人欣喜, 耗时能够维持在1ms以内, 优化提升效果很明显.

总结:
  总的来说, 这也是jaxb在使用过程的一个坑, 如果线上应用, 切记改为下面的方式优化, ^_^, 本文没有深入研究为何JAXBContext.newInstance代价这么高昂, 只是得出了一个小结论, 权当笔记.

JAXB性能优化的更多相关文章

  1. JVM性能优化系列-(3) 虚拟机执行子系统

    3. 虚拟机执行子系统 3.1 Java跨平台的基础 Java刚诞生的宣传口号:一次编写,到处运行(Write Once, Run Anywhere),其中字节码是构成平台无关的基石,也是语言无关性的 ...

  2. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  3. 03.SQLServer性能优化之---存储优化系列

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概  述:http://www.cnblogs.com/dunitian/p/60413 ...

  4. Web性能优化:What? Why? How?

    为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...

  5. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  6. C#中那些[举手之劳]的性能优化

    隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...

  7. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

  8. 02.SQLServer性能优化之---牛逼的OSQL----大数据导入

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 上一篇:01.SQLServer性能优化之----强大的文件组----分盘存储 http ...

  9. C++ 应用程序性能优化

    C++ 应用程序性能优化 eryar@163.com 1. Introduction 对于几何造型内核OpenCASCADE,由于会涉及到大量的数值算法,如矩阵相关计算,微积分,Newton迭代法解方 ...

随机推荐

  1. 一、集合框架(Collection和Collections的区别)

    一.Collection和Map 是一个接口 Collection是Set,List,Queue,Deque的接口 Set:无序集合,List:链表,Queue:先进先出队列,Deque:双向链表 C ...

  2. linux -- 基于zookeeper搭建yarn的HA高可用集群

    linux -- 基于zookeeper搭建yarn的HA高可用集群 实现方式:配置yarn-site.xml配置文件 <configuration> <property> & ...

  3. java中super和this的使用

    要说super就先要说this."this",作为一个特殊的关键字,它的规则如下: 1.可以表示构造函数传递.this(a,b)表示调用另外一个构造函数.这里面的this就是一个特 ...

  4. [LeetCode] 111. Minimum Depth of Binary Tree ☆(二叉树的最小深度)

    [Leetcode] Maximum and Minimum Depth of Binary Tree 二叉树的最小最大深度 (最小有3种解法) 描述 解析 递归深度优先搜索 当求最大深度时,我们只要 ...

  5. PyCharm+Scrapy爬取安居客楼盘信息

    一.说明 1.1 开发环境说明 开发环境--PyCharm 爬虫框架--Scrapy 开发语言--Python 3.6 安装第三方库--Scrapy.pymysql.matplotlib 数据库--M ...

  6. Windows Server 2003添加防火墙策略教程

    1.开始--控制面板--Windows防火墙 2.启用 选择启用即启动防火墙 3.添加例外 常常启用防火墙,还是希望某端口能被某些IP所访问,而防火墙默认是禁止所有IP访问本机的所有端口的,此时我们就 ...

  7. 接收上传的multi-file的文件(四)

    构建工程 为例创建一个springmvc工程你需要spring-boot-starter-thymeleaf和 spring-boot-starter-web的起步依赖.为例能够上传文件在服务器,你需 ...

  8. c++ count函数

    count函数 algorithm头文件(#include <algorithm>)定义了一个count的函数,其功能类似于find.这个函数使用一对迭代器和一个值做参数,返回这个值出现次 ...

  9. 【HTTP】boundary 中一个 = 导致HTTP上传文件失败

    (1)#define ABOUNDARY "----=_Resume_002_0CE7_01D1C649.298A8070" (2)#define ABOUNDARY " ...

  10. [转载] C++ STL中判断list为空,size()==0和empty()有什么区别

    关于两个的区别,首先size()==0为bool表达式,empty()为函数调用,这一点很明显.查看源代码, bool empty() const { return _M_node->_M_ne ...