FastJSON定义: FastJSON是一个阿里巴巴内部人员开发的,用于JSON对象和普通类对象互相转换的库。号称性能超越Jackson,今天我们就来看看,阿里巴巴大牛 vs Tatu Saloranta,到底 who is the most awesome!
FastJSON原理:
-对象 to JSON :利用反射找到对象类的所有Get方法,然后把"get"去掉,小写化,作为JSON的每个key值,如 getA 对应的key值为 a,而与真实的类成员名无关。
-JSON to pojo :先同样通过反射找到对象类所有的Set方法,然后使用无参数构造函数(所以一定要有无参数的构造函数)新建一个类对象,从JSON字符串中取出一个key 如 a,先大写化为A,那么从所有Set方法中找到 SetA(),然后进行赋值。 如果找不到 setA (seta也不行),那么该值被忽略,也不报错。
Jackson 的原理和FastJson一致,但是在 JSON to Java pojo的步骤中,做了更加科学的check,因而能识别seta这样的小写。但是如果getA 和geta都找不到,则会抛出异常(除非把a设置为忽略)。
其他的步骤原理和FastJSON类似。
测试验证代码:
package jar;
import com.alibaba.fastjson.JSON;
public class Test{
private int aaa=0;
private String bbb = "000";
public Test() {
// TODO Auto-generated constructor stub
aaa = 1;
bbb = "111";
System.out.println(" default construct function is called!!!");
}
public Test(int a ,String b) {
// TODO Auto-generated constructor stub
aaa = a;
bbb = b;
System.out.println("construct 2 function is called!!!");
}
public int getA() {
return aaa;
}
public void seta(int a)
{
this.aaa =a;
}
public String getB() {
return bbb;
}
//test
public static void main(String[] args) throws Exception
{
Test test =new Test(2,"222");
String code = JSON.toJSONString(test);
System.out.println(code);
Test reverse = JSON.parseObject(code,Test.class);
System.out.println(reverse.getA());
System.out.println(reverse.getB());
}
}
下面是对 FastJson 和 Jackson (pojo to json-编码) 以及 (json to pojo-解码)以及综合(编码+解码) 在不同成员数量 下 ,不同循环次数的耗时(ns纳秒)对比。
// code + decode -----------------------------------------------------
// 10000 - 23 members
// Jackson :235750737 ns
// FastJSON:347795550 ns
// 10000 - 2 members
// Jackson :164173126 ns
// FastJSON:159078284 ns
// 100000 - 23 members
// Jackson :1004902734 ns
// FastJSON:1689072614 ns
// 100000 - 2 members
// Jackson :392344461 ns
// FastJSON:299521240 ns
// 1000000 - 23 members
// Jackson :8547741285 ns
// FastJSON:15377369425 ns
// 1000000 - 2 members
// Jackson :2581267623 ns
// FastJSON:1591827729 ns
// code only -------------------------------------------------------
// 10000 - 23 members
// Jackson :115036100 ns
// FastJSON:158681243 ns
// 10000 - 2 members
// Jackson :87886170 ns
// FastJSON:103086025 ns
// 100000 - 23 members
// Jackson :417539325 ns
// FastJSON:349358062 ns
// 100000 - 2 members
// Jackson :185865488 ns
// FastJSON:144893485 ns
// 1000000 - 23 members
// Jackson :3384171740 ns
// FastJSON:2200190119 ns
// 1000000 - 2 members
// Jackson :1193815955 ns
// FastJSON:568776506 ns
// decode only -------------------------------------------------------
// 10000 - 23 members
// Jackson :122597862 ns
// FastJSON:183567261 ns
// 10000 - 2 members
// Jackson :75418145 ns
// FastJSON:47832689 ns
// 100000 - 23 members
// Jackson :497670344 ns
// FastJSON:1254994458 ns
// 100000 - 2 members
// Jackson :165368101 ns
// FastJSON:117555618 ns
// 1000000 - 23 members
// Jackson :4189147981 ns
// FastJSON:12004873228 ns
// 1000000 - 2 members
// Jackson :999578584 ns
// FastJSON:863444723 ns
结论:
编码(pojo to json): 当循环数量较小时,FastJSON的性能 低于 JackSON;
当循环数量越大时,FastJSON的性能开始超过Jackson;
解码( json to pojo):当成员数量越大时,FastJSON的相对性能越差,JackSON的相对性能则越好;
当成员数量越小时,FastJSON的性能越好。
综合(编码+解码): 当成员变量数量越大时,Jackson 获胜。无关于循环数量。
当成员变量数量越小时,FastJSON获胜。
一般情况下,系统中的循环数量一般不会大的惊人,应该是偏小的。而成员变量变多,是一个企业级系统常见的情况。
SO, who is the most fast or best? 我就不点出了。
。。。
Whatever, 两个JSON框架都是很棒的。而且本人很喜欢FastJSON的易用性,干净。
有时间,有兴趣的可以继续研究研究FastJSON在多成员变量解码时的劣势是什么原因导致的。
付上测试代码:
package jar;
import java.io.StringWriter;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import com.alibaba.fastjson.JSON;
public class Test{
private int aaa=0;
private String bbb = "000";
private String c1 = "000";
private String c2 = "000";
private String c3 = "000";
private String c4 = "000";
private String c5 = "000";
private String c6 = "000";
private String c7 = "000";
private String c8 = "000";
private String c9 = "000";
private String c10 = "000";
private String c11 = "000";
private String c12 = "000";
private String c13 = "000";
private String c14 = "000";
private String c15 = "000";
private String c16 = "000";
private String c17 = "000";
private String c18 = "000";
private String c19 = "000";
private String c20 = "000";
private String c21 = "000";
public Test()
{
}
public Test(int a ,String b) {
// TODO Auto-generated constructor stub
aaa = a;
bbb = b;
//System.out.println("construct 2 function is called!!!");
}
public int getA() {
return aaa;
}
public void setA(int a)
{
this.aaa = a;
}
public String getB() {
return bbb;
}
public void setB(String b) {
this.bbb = b;
}
public String getC1() {
return c1;
}
public void setC1(String c1) {
this.c1 = c1;
}
public String getC2() {
return c2;
}
public void setC2(String c2) {
this.c2 = c2;
}
public String getC3() {
return c3;
}
public void setC3(String c3) {
this.c3 = c3;
}
public String getC4() {
return c4;
}
public void setC4(String c4) {
this.c4 = c4;
}
public String getC5() {
return c5;
}
public void setC5(String c5) {
this.c5 = c5;
}
public String getC6() {
return c6;
}
public void setC6(String c6) {
this.c6 = c6;
}
public String getC7() {
return c7;
}
public void setC7(String c7) {
this.c7 = c7;
}
public String getC8() {
return c8;
}
public void setC8(String c8) {
this.c8 = c8;
}
public String getC9() {
return c9;
}
public void setC9(String c9) {
this.c9 = c9;
}
public String getC10() {
return c10;
}
public void setC10(String c10) {
this.c10 = c10;
}
public String getC11() {
return c11;
}
public void setC11(String c11) {
this.c11 = c11;
}
public String getC12() {
return c12;
}
public void setC12(String c12) {
this.c12 = c12;
}
public String getC13() {
return c13;
}
public void setC13(String c13) {
this.c13 = c13;
}
public String getC14() {
return c14;
}
public void setC14(String c14) {
this.c14 = c14;
}
public String getC15() {
return c15;
}
public void setC15(String c15) {
this.c15 = c15;
}
public String getC16() {
return c16;
}
public void setC16(String c16) {
this.c16 = c16;
}
public String getC17() {
return c17;
}
public void setC17(String c17) {
this.c17 = c17;
}
public String getC18() {
return c18;
}
public void setC18(String c18) {
this.c18 = c18;
}
public String getC19() {
return c19;
}
public void setC19(String c19) {
this.c19 = c19;
}
public String getC20() {
return c20;
}
public void setC20(String c20) {
this.c20 = c20;
}
public String getC21() {
return c21;
}
public void setC21(String c21) {
this.c21 = c21;
}
//test
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
Test test =new Test(2,"222");
//JackJSON 初始化
ObjectMapper objectMapper = new ObjectMapper();
long startTime=0; //获取开始时间
long endTime=0; //获取结束时间
int loopCount =100000;
// code + decode -----------------------------------------------------
// 10000 - 23 members
// Jackson :235750737 ns
// FastJSON:347795550 ns
// 10000 - 2 members
// Jackson :164173126 ns
// FastJSON:159078284 ns
// 100000 - 23 members
// Jackson :1004902734 ns
// FastJSON:1689072614 ns
// 100000 - 2 members
// Jackson :392344461 ns
// FastJSON:299521240 ns
// 1000000 - 23 members
// Jackson :8547741285 ns
// FastJSON:15377369425 ns
// 1000000 - 2 members
// Jackson :2581267623 ns
// FastJSON:1591827729 ns
// code only -------------------------------------------------------
// 10000 - 23 members
// Jackson :115036100 ns
// FastJSON:158681243 ns
// 10000 - 2 members
// Jackson :87886170 ns
// FastJSON:103086025 ns
// 100000 - 23 members
// Jackson :417539325 ns
// FastJSON:349358062 ns
// 100000 - 2 members
// Jackson :185865488 ns
// FastJSON:144893485 ns
// 1000000 - 23 members
// Jackson :3384171740 ns
// FastJSON:2200190119 ns
// 1000000 - 2 members
// Jackson :1193815955 ns
// FastJSON:568776506 ns
// decode only -------------------------------------------------------
// 10000 - 23 members
// Jackson :122597862 ns
// FastJSON:183567261 ns
// 10000 - 2 members
// Jackson :75418145 ns
// FastJSON:47832689 ns
// 100000 - 23 members
// Jackson :497670344 ns
// FastJSON:1254994458 ns
// 100000 - 2 members
// Jackson :165368101 ns
// FastJSON:117555618 ns
// 1000000 - 23 members
// Jackson :4189147981 ns
// FastJSON:12004873228 ns
// 1000000 - 2 members
// Jackson :999578584 ns
// FastJSON:863444723 ns
//Jackson
startTime = System.nanoTime();
for(int i=0;i<loopCount;i++)
{
StringWriter sw = new StringWriter();
JsonGenerator jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(sw);
jsonGenerator.writeObject(test);
String result = sw.toString();
// Test acc = objectMapper.readValue(result, Test.class);
}
endTime = System.nanoTime();
System.out.println("Jackson :"+(endTime-startTime)+" ns");
startTime = System.nanoTime();
//FastJSON
for(int i=0;i<loopCount;i++)
{
String code = JSON.toJSONString(test);
// Test reverse = JSON.parseObject(code,Test.class);
}
endTime = System.nanoTime();
System.out.println("FastJSON:"+(endTime-startTime)+" ns");
}
}
还有一篇TS回复挑战者的基准测试结果的文章,虽然和本文没有直接关系,但是反映了一些东西。可以了解了解。
http://www.infoq.com/cn/news/2014/05/jackson-founder-responds