JAXB性能优化
前言:
之前在查阅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性能优化的更多相关文章
- JVM性能优化系列-(3) 虚拟机执行子系统
3. 虚拟机执行子系统 3.1 Java跨平台的基础 Java刚诞生的宣传口号:一次编写,到处运行(Write Once, Run Anywhere),其中字节码是构成平台无关的基石,也是语言无关性的 ...
- 01.SQLServer性能优化之----强大的文件组----分盘存储
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...
- 03.SQLServer性能优化之---存储优化系列
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概 述:http://www.cnblogs.com/dunitian/p/60413 ...
- Web性能优化:What? Why? How?
为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...
- Web性能优化:图片优化
程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...
- C#中那些[举手之劳]的性能优化
隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...
- JavaScript性能优化
如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...
- 02.SQLServer性能优化之---牛逼的OSQL----大数据导入
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 上一篇:01.SQLServer性能优化之----强大的文件组----分盘存储 http ...
- C++ 应用程序性能优化
C++ 应用程序性能优化 eryar@163.com 1. Introduction 对于几何造型内核OpenCASCADE,由于会涉及到大量的数值算法,如矩阵相关计算,微积分,Newton迭代法解方 ...
随机推荐
- 二十、MVC的WEB框架(Spring MVC)
一.Spring MVC 运行原理:客户端请求提交到DispatcherServlet,由DispatcherServlet控制器查询HandlerMapping,找到并分发到指定的Controlle ...
- InnoDB存储引擎表的主键
在InnoDB存储引擎中,表是按照主键顺序组织存放的.在InnoDB存储引擎表中,每张表都有主键(primary key),如果在创建表时没有显式地定义主键,则InnoDB存储引擎会按如下方式选择或创 ...
- Tomcat和JDK版本的对应关系
当我们在谈论Tomcat与JDK版本的对应关系的时候,我们实际上在讨论两个问题. 第一个是,我们想安装了某个版本的Tomcat(比如Tomcat7),需要安装哪个版本的JDK,才能把Tomcat运行起 ...
- windows工具打开命令
程序 命令 位置 记事本 notepad C:\Windows\system32 ping ping C:\Windows\System32 服务管理器 services.msc C:\Windows ...
- matlab中高维数组怎么做PCA?
PCA需要先求数据的散布矩阵x*x',再求其特征向量,那么随便一个400*450的图像,就是180000维,矩阵就是180000*180000,matlab无法容纳,那么通常的PCA对图像的降维,比如 ...
- JAVA的环境变量配置(方式二)
1.想要成功配置Java的环境变量,那肯定就要安装JDK(JDK安装包在方式一中),才能开始配置的. 2.安装JDK 向导进行相关参数设置.如图: 3.正在安装程序的相关功能,如图: 4.选择安装的路 ...
- java中构造方法和方法全面解析
构造方法和方法的区别: 构造方法要与类名相同,无返回类型,在类初始化的时候调用. 方法最好与类名不同,对象调用,静态方法可用类名.方法(). 构造器和方法在下面三个方面区别:修饰符,返回值, ...
- IO多路复用,select、poll、epoll 编程主要步骤
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 直接插入排序(Straight Insertion Sort)
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- Linux3.10.0块IO子系统流程(3)-- SCSI策略例程
很长时间以来,Linux块设备使用了一种称为“蓄流/泄流”(plugging/unplugging)的技术来改进吞吐率.简单而言,这种工作方式类似浴盆排水系统的塞子.当IO被提交时,它被储存在一个队列 ...