JSON的应用库Jackson和Fastjson的性能差距这么大吗?
1.概述
在JSON领域,有两个应用库包比较流行,基本上是国外以Jackson为主,国内以阿里出品的Fastjson为主。两者都提供了非常优秀的json处理能力和设计机制,实际应用中具体使用那一个,更多的应该是以项目和公司的要求为准吧。
但是,我这里对两个库的常规普遍应用场景做了简单的性能测试,或许对有些借鉴意义。
2.第一次:对象JSON化
创建一个对象,以及对象数据中含有引用数据对象。简单创建10个对象进行数据的JSON化处理。
2.1 测试环境概括如下:
操作系统:windows10,Java:JDK12;
笔记本:华为 Mate D,
电脑型号华为 MRC-WX0 笔记本电脑 (扫描时间:2019年05月20日)
操作系统Windows 10 专业版 64位 ( DirectX 12 )
处理器英特尔 Core i7-8550U @ 1.80GHz 四核
主板华为 MRC-WX0-PCB ( 7th Generation Intel Processor Family I/O - 9D4E 笔记本芯片组 )
内存8 GB ( 海力士 DDR4 2400MHz )
主硬盘建兴 CV8-8E128 ( 128 GB / 固态硬盘 )
显卡Nvidia GeForce MX150 ( 2 GB )
显示器京东方 BOE070C ( 15.5 英寸 )
声卡瑞昱 Audio @ 英特尔 High Definition Audio 控制器
网卡英特尔 Dual Band Wireless-AC 8265
Eclipse:Version: 2019-03 (4.11.0);
Jackson:Version 2.9.10
Fastjson:Version 1.2.61
2.2. 测试代码
第一次测试:
POJO代码如下:
package com.newday.jsonvs;
public class PojoBean {
private String name ;
private double price ;
private Address address ;
public PojoBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
PojoBean(String name, double price, Address address) {
super();
this.name = name;
this.price = price;
this.address = address;
}
}
class Address {
private String code ;
private String detail ;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
Address(String code, String detail) {
super();
this.code = code;
this.detail = detail;
}
}
主体测试代码如下:
package com.newday.jsonvs;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MainTest {
public MainTest() {
}
public static void main(String[] args) throws JsonProcessingException {
//待序列化为json的POJO
PojoBean[] beans =new PojoBean[10] ;
for(int i=0;i<10;i++) {
double dn =Math.random() ;
Address ad = new Address(""+Math.round(dn*100),"address@"+dn);
beans[i] = new PojoBean("name-"+i,Math.random()*100,ad) ;
}
long start = System.currentTimeMillis();
String fastjson = JSON.toJSONString(beans);//静态方法
long end = System.currentTimeMillis() ;
long total = end - start;
System.out.println("FastJSON耗时:"+total);
System.out.println("jsondata:\n"+fastjson);
start = System.currentTimeMillis();
ObjectMapper om = new ObjectMapper();
String jackson = om.writeValueAsString(beans);
end = System.currentTimeMillis();
total = end-start ;
System.out.println("Jackson耗时:\n"+total);
System.out.println("jacksondata:\n"+jackson);
}
}
首次运行结果如下:
FastJSON耗时:763
jsondata:
[{"address":{"code":"8","detail":"[email protected]"},"name":"name-0","price":33.427612459933655},{"address":{"code":"22","detail":"[email protected]"},"name":"name-1","price":33.566846591341495},{"address":{"code":"78","detail":"[email protected]"},"name":"name-2","price":68.21633137741367},{"address":{"code":"88","detail":"[email protected]"},"name":"name-3","price":11.320935472309612},{"address":{"code":"23","detail":"[email protected]"},"name":"name-4","price":81.01397274124294},{"address":{"code":"90","detail":"[email protected]"},"name":"name-5","price":74.35559885425273},{"address":{"code":"42","detail":"[email protected]"},"name":"name-6","price":79.75691824866819},{"address":{"code":"93","detail":"[email protected]"},"name":"name-7","price":52.53806695117041},{"address":{"code":"32","detail":"[email protected]"},"name":"name-8","price":27.377690148333166},{"address":{"code":"30","detail":"[email protected]"},"name":"name-9","price":19.91192118153473}]
Jackson耗时:
410
jacksondata:
[{"name":"name-0","price":33.427612459933655,"address":{"code":"8","detail":"[email protected]"}},{"name":"name-1","price":33.566846591341495,"address":{"code":"22","detail":"[email protected]"}},{"name":"name-2","price":68.21633137741367,"address":{"code":"78","detail":"[email protected]"}},{"name":"name-3","price":11.320935472309612,"address":{"code":"88","detail":"[email protected]"}},{"name":"name-4","price":81.01397274124294,"address":{"code":"23","detail":"[email protected]"}},{"name":"name-5","price":74.35559885425273,"address":{"code":"90","detail":"[email protected]"}},{"name":"name-6","price":79.75691824866819,"address":{"code":"42","detail":"[email protected]"}},{"name":"name-7","price":52.53806695117041,"address":{"code":"93","detail":"[email protected]"}},{"name":"name-8","price":27.377690148333166,"address":{"code":"32","detail":"[email protected]"}},{"name":"name-9","price":19.91192118153473,"address":{"code":"30","detail":"[email protected]"}}]
从上面的数据来看,Jackson更好使,时间多用了763-410=353,两者相差将近过半。
第二次测试运行,对10万个map进行Json化处理,看看运行查看结果,这次主要是主体测试代码如下:
ObjectMapper om = new ObjectMapper() ;
Map<String,String> map = new HashMap<String,String>();
for(int i=1;i<=100000;i++) {
map.put("k"+i,"V"+i);
}
try {
long start = System.currentTimeMillis();
String jackson = om.writeValueAsString(map);
long totaltime = System.currentTimeMillis() - start ;
System.out.println("Jackson耗时:"+totaltime);
//System.out.println("jacksondata:\n"+jackson);
start = System.currentTimeMillis();
String fastjson = JSONObject.toJSONString(map);
totaltime = System.currentTimeMillis() - start ;
System.out.println("Fastjson耗时:"+totaltime);
//System.out.println("FastjsonData:\n"+fastjson);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
总体运行输出如下:
Jackson耗时:86
Fastjson耗时:149
两次运行相差都这么大?也基本类似,相差一半左右。
我在专栏里,专门写了Jackson的应用指南,每次都是new个ObjectMapper对象,那这次,我班创建对象的时间也算在这里面,看看时间相差情况。调整一下测试代码,主体测试代码如下(10万个map不变):
long start = System.currentTimeMillis();//计算创建对象的时间
ObjectMapper om = new ObjectMapper() ;
String jackson = om.writeValueAsString(map);
long totaltime = System.currentTimeMillis() - start ;
System.out.println("Jackson耗时:"+totaltime);
//System.out.println("jacksondata:\n"+jackson);
start = System.currentTimeMillis();
String fastjson = JSONObject.toJSONString(map);//静态方法
totaltime = System.currentTimeMillis() - start ;
System.out.println("Fastjson耗时:"+totaltime);
这次运行结果如下:
Jackson耗时:383
Fastjson耗时:104
什么情况?创建ObjectMapper对象开销很大啊……?!
通过对比,忽略创建ObjectMapper对象的时间,用静态工厂方法来创建Jackson对象,然后复用此对象,会极大的提高Jackson的数据处理效率。
所以,基于这一点来讲,Jackson进行JSON化数据处理时,其效率会高出Fastjson几倍!!而FastJson的妙处就是傻瓜化为你提供了开箱即用的便捷,不需要我们考虑其它的事情——赖,就得有赖的代价吧——这也许是你可以承担的。
那那序列化呢,效果会怎样?你可以自己测试一把——今天中午酒有点多,就不写了,各位有情趣的可以自己测试一把啊。^_^