JSON的应用库Jackson和Fastjson的性能差距这么大吗?

1.概述

在JSON领域,有两个应用库包比较流行,基本上是国外以Jackson为主,国内以阿里出品的Fastjson为主。两者都提供了非常优秀的json处理能力和设计机制,实际应用中具体使用那一个,更多的应该是以项目和公司的要求为准吧。

但是,我这里对两个库的常规普遍应用场景做了简单的性能测试,或许对有些借鉴意义。

JSON的应用库Jackson和Fastjson的性能差距这么大吗?

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":"address@0.07804243774069097"},"name":"name-0","price":33.427612459933655},{"address":{"code":"22","detail":"address@0.22484155502727166"},"name":"name-1","price":33.566846591341495},{"address":{"code":"78","detail":"address@0.7811265697079444"},"name":"name-2","price":68.21633137741367},{"address":{"code":"88","detail":"address@0.8808975084079629"},"name":"name-3","price":11.320935472309612},{"address":{"code":"23","detail":"address@0.2269763081570001"},"name":"name-4","price":81.01397274124294},{"address":{"code":"90","detail":"address@0.901489041811746"},"name":"name-5","price":74.35559885425273},{"address":{"code":"42","detail":"address@0.41562889870929476"},"name":"name-6","price":79.75691824866819},{"address":{"code":"93","detail":"address@0.9271631680355852"},"name":"name-7","price":52.53806695117041},{"address":{"code":"32","detail":"address@0.322583685181389"},"name":"name-8","price":27.377690148333166},{"address":{"code":"30","detail":"address@0.2982434772886601"},"name":"name-9","price":19.91192118153473}]

Jackson耗时:

410

jacksondata:

[{"name":"name-0","price":33.427612459933655,"address":{"code":"8","detail":"address@0.07804243774069097"}},{"name":"name-1","price":33.566846591341495,"address":{"code":"22","detail":"address@0.22484155502727166"}},{"name":"name-2","price":68.21633137741367,"address":{"code":"78","detail":"address@0.7811265697079444"}},{"name":"name-3","price":11.320935472309612,"address":{"code":"88","detail":"address@0.8808975084079629"}},{"name":"name-4","price":81.01397274124294,"address":{"code":"23","detail":"address@0.2269763081570001"}},{"name":"name-5","price":74.35559885425273,"address":{"code":"90","detail":"address@0.901489041811746"}},{"name":"name-6","price":79.75691824866819,"address":{"code":"42","detail":"address@0.41562889870929476"}},{"name":"name-7","price":52.53806695117041,"address":{"code":"93","detail":"address@0.9271631680355852"}},{"name":"name-8","price":27.377690148333166,"address":{"code":"32","detail":"address@0.322583685181389"}},{"name":"name-9","price":19.91192118153473,"address":{"code":"30","detail":"address@0.2982434772886601"}}]

从上面的数据来看,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的妙处就是傻瓜化为你提供了开箱即用的便捷,不需要我们考虑其它的事情——赖,就得有赖的代价吧——这也许是你可以承担的。

那那序列化呢,效果会怎样?你可以自己测试一把——今天中午酒有点多,就不写了,各位有情趣的可以自己测试一把啊。^_^