前言:
  之前在查阅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. 4.Liunx磁盘管理

    1.磁盘管理:df .du 2.磁盘加载:mount. umount 3.磁盘分区:fdisk 1.df -h 查看硬件

  2. 关于Oracle RAC中SCN原理和机制的探索

    今天看书时看到了关于RAC中SCN的问题,为了进一步搞清楚其内部原理和机制,对该问题进行了广泛的查阅和搜索,遗憾的是,可以参考的资料很少,网上大部分是人云亦云的帖子,其中,详细介绍其内部原理和机制的资 ...

  3. 【转】vue.js表单校验详解

    官方文档:https://monterail.github.io/vuelidate/ https://github.com/monterail/vuelidate 1.npm安装vue-valida ...

  4. js正则表达式 replace替换url的参数

    /* 定义替换对象键值 */var setReferArgs = function(){    var referArgs = new Object();    referArgs['#userID\ ...

  5. List<Map<String, Object>>取值

    List<Map<String, Object>> postlist //一个list里面装着多个map,如下 [ {A=0100, B=4}, {A=0200, B=3}, ...

  6. ubuntu16.10 中安装mysql

    1.安装MYSQL: root@ubuntu:~# sudo apt-get install mysql-server root@ubuntu:~# apt isntall mysql-client ...

  7. linux系统管理 启停命令

    mac下Linux的登录命名 'ssh -l root 192.168.10.109' password: xxxx ​ 退出登录 >> logout shutdown命令 要使用这个命令 ...

  8. while循环以及格式化输出总结

    while循环: while 无限循环 count = 1 sum = 0 while True: sum = sum + count count = count + 1 if count == 10 ...

  9. 【资料收集】QT 环境安装配置

    (很详细,极力推荐) [OpenCV] -- win7下配置OpenCV的Qt开发环境 - 代码人生 - 博客频道 - CSDN.NET  http://blog.csdn.net/qiurisuix ...

  10. docker samba

    这个就是匿名用户可以登录访问,不能写. root登录,就可以写了. #命令,是在物理机上运行的. 主要是根据dockerfile构建镜像. 启动容器 进入镜像 设置root密码. 附smb.conf ...