FastJSON 原理剖析 以及 和 Jackson的对比 who is the most fast!
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类似。
测试验证代码:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
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纳秒)对比。
[java] view plaincopy在CODE上查看代码片派生到我的代码片
// 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的相对性能则越好;
综合(编码+解码): 当成员变量数量越大时,Jackson 获胜。无关于循环数量。
当成员变量数量越小时,FastJSON获胜。
一般情况下,系统中的循环数量一般不会大的惊人,应该是偏小的。而成员变量变多,是一个企业级系统常见的情况。
SO, who is the most fast or best? 我就不点出了。
。。。
Whatever, 两个JSON框架都是很棒的。而且本人很喜欢FastJSON的易用性,干净。
有时间,有兴趣的可以继续研究研究FastJSON在多成员变量解码时的劣势是什么原因导致的。
付上测试代码:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
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"); } }