前言
在开发过程中,经常会遇到将对象转为response返回出去,或着将request转PO,又或者将PO转为VO的场景。
下面就对比下:hutool,fastjson,jackson,jdk的效率
一、准备工作
1、导入依赖
jdk版本1.8
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
2、PO对象
@Data
public class ParentPO {
private String name;
private List<ChildPO> childList;
private WifePO wife;
public ParentPO() {
}
public ParentPO(String name, List<ChildPO> childList, WifePO wife) {
this.name = name;
this.childList = childList;
this.wife = wife;
}
}
@Data
public class ChildPO {
private String name;
public ChildPO(String name) {
this.name = name;
}
}
@Data
public class WifePO {
private String name;
public WifePO(String name) {
this.name = name;
}
}
3、 response对象
@Data
public class ParentResponse implements Serializable {
private String name;
private List<ChildResponse> childList;
private WifeResponse wife;
public ParentResponse() {
}
}
@Data
public class ChildResponse implements Serializable {
private String name;
public ChildResponse() {
}
public ChildResponse(String name) {
this.name = name;
}
}
@Data
public class WifeResponse implements Serializable {
private String name;
public WifeResponse() {
}
public WifeResponse(String name) {
this.name = name;
}
}
二、比较代码
package com.example.demo.demo2;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.python.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
public class Demo2Controller {
public static Integer CHILD_NUM = 2;
public static ParentPO getParent() {
List<ChildPO> childPOList = getChildList();
return new ParentPO("张", childPOList, new WifePO("李"));
// return new ParentPO("张", Lists.newArrayList(new ChildPO("1"),new ChildPO("2"),new ChildPO("3"),new ChildPO("4")), new WifePO("李"));
}
private static List<ChildPO> getChildList() {
List<ChildPO> childPOList = new ArrayList<>();
while (CHILD_NUM > 0) {
childPOList.add(new ChildPO("" + CHILD_NUM--));
}
return childPOList;
}
public static void main(String[] args) throws Exception {
Long start1 = System.currentTimeMillis();
ParentPO p1 = getParent();
Long end1 = System.currentTimeMillis();
System.out.println("创建parent耗时 = " + (end1 - start1));
System.out.println("创建parent = " + JSONObject.toJSONString(p1));
Long start2 = System.currentTimeMillis();
ParentResponse p2 = BeanUtil.toBean(p1, ParentResponse.class);
Long end2 = System.currentTimeMillis();
System.out.println("hutool赋值到Parent2耗时 = " + (end2 - start2));
System.out.println("hutool赋值到Parent2 = " + JSONObject.toJSONString(p2));
Long start3 = System.currentTimeMillis();
ParentResponse p3 = JSONObject.parseObject(JSONObject.toJSONString(p1), ParentResponse.class);
Long end3 = System.currentTimeMillis();
System.out.println("fastjson赋值到Parent2耗时 = " + (end3 - start3));
System.out.println("fastjson赋值到Parent2 = " + JSONObject.toJSONString(p3));
Long start4 = System.currentTimeMillis();
ObjectMapper mapper = new ObjectMapper();
ParentResponse p4 = mapper.readValue(mapper.writeValueAsString(p2), ParentResponse.class);
Long end4 = System.currentTimeMillis();
System.out.println("jackson赋值到Parent2耗时 = " + (end4 - start4));
System.out.println("jackson赋值到Parent2 = " + JSONObject.toJSONString(p4));
Long start5 = System.currentTimeMillis();
ParentResponse p5 = BeanUtil.toBean(p1, ParentResponse.class);
BeanUtils.copyProperties(p1, p5);
Long end5 = System.currentTimeMillis();
System.out.println("jdk赋值到Parent2耗时 = " + (end5 - start5));
System.out.println("jdk赋值到Parent2 = " + JSONObject.toJSONString(p5));
}
}
用CHILD_NUM控制parent对象的大小(parent有N个child)
当CHILD_NUM = 5时,执行结果如下:
创建parent耗时 = 2
hutool赋值到Parent2耗时 = 139
fastjson赋值到Parent2耗时 = 127
jackson赋值到Parent2耗时 = 235
jdk赋值到Parent2耗时 = 105
当CHILD_NUM = 50时,执行结果如下:
创建parent耗时 = 1
hutool赋值到Parent2耗时 = 171
fastjson赋值到Parent2耗时 = 125
jackson赋值到Parent2耗时 = 238
jdk赋值到Parent2耗时 = 141
当CHILD_NUM = 500时,执行结果如下:
创建parent耗时 = 3
hutool赋值到Parent2耗时 = 274
fastjson赋值到Parent2耗时 = 117
jackson赋值到Parent2耗时 = 222
jdk赋值到Parent2耗时 = 178
当CHILD_NUM =5000时,执行结果如下:
创建parent耗时 = 8
hutool赋值到Parent2耗时 = 738
fastjson赋值到Parent2耗时 = 158
jackson赋值到Parent2耗时 = 269
jdk赋值到Parent2耗时 = 547
当CHILD_NUM = 50000时,执行结果如下:
创建parent耗时 = 30
hutool赋值到Parent2耗时 = 4785
fastjson赋值到Parent2耗时 = 187
jackson赋值到Parent2耗时 = 285
jdk赋值到Parent2耗时 = 3997
总结
从结果上来看,综合选择fastjson,效率是比较高的。
hutool速度为啥那么慢呢,从方法上看,是因为使用了反射(反射技术速度慢)
public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
return toBean(source, () -> {
return ReflectUtil.newInstanceIfPossible(clazz);
}, options);
}
jdk也是内部使用了反射,所以速度慢
这个方法内使用反射实现copy
org.springframework.beans.BeanUtils#copyProperties(java.lang.Object, java.lang.Object, java.lang.Class<?>, java.lang.String...)
fastjson快的原因:继承JSON,本质上是转为Map
jackson不知道(代码没看懂)