分享

FastJSON原理剖析以及和Jackson的对比whoisthemostfast!

 好闺女瑶瑶 2015-12-21

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类似。


测试验证代码:

  1. package jar;  
  2.   
  3. import com.alibaba.fastjson.JSON;  
  4.   
  5. public class Test{  
  6.       
  7.       
  8.     private int aaa=0;  
  9.     private String bbb = "000";  
  10.       
  11.       
  12.       
  13.     public Test() {  
  14.         // TODO Auto-generated constructor stub  
  15.         aaa = 1;  
  16.         bbb = "111";  
  17.         System.out.println(" default construct function is called!!!");  
  18.     }  
  19.       
  20.     public Test(int a ,String b) {  
  21.         // TODO Auto-generated constructor stub  
  22.         aaa = a;  
  23.         bbb = b;  
  24.         System.out.println("construct 2 function is called!!!");  
  25.     }  
  26.       
  27.   
  28.     public int getA() {  
  29.         return aaa;  
  30.     }  
  31.   
  32.   
  33.     public void seta(int a)  
  34.     {  
  35.         this.aaa =a;  
  36.     }  
  37.       
  38.     public String getB() {  
  39.         return bbb;  
  40.     }  
  41.   
  42.       
  43.       
  44.       
  45.      //test  
  46.      public static void main(String[] args) throws Exception    
  47.      {         
  48.            
  49.            Test test =new Test(2,"222");  
  50.            String code =  JSON.toJSONString(test);  
  51.            System.out.println(code);  
  52.            Test reverse = JSON.parseObject(code,Test.class);  
  53.   
  54.            System.out.println(reverse.getA());  
  55.            System.out.println(reverse.getB());  
  56.      }  
  57.   
  58. }  


下面是对 FastJson 和 Jackson  (pojo to json-编码) 以及 (json to pojo-解码)以及综合(编码+解码) 在不同成员数量 下 ,不同循环次数的耗时(ns纳秒)对比。


  1. //         code + decode -----------------------------------------------------  
  2. //         10000  - 23 members  
  3. //         Jackson :235750737 ns  
  4. //         FastJSON:347795550 ns  
  5. //         10000  - 2 members  
  6. //         Jackson :164173126 ns  
  7. //         FastJSON:159078284 ns  
  8.              
  9.              
  10. //         100000 - 23 members  
  11. //         Jackson :1004902734 ns  
  12. //         FastJSON:1689072614 ns  
  13. //         100000 - 2 members   
  14. //         Jackson :392344461 ns  
  15. //         FastJSON:299521240 ns  
  16.              
  17. //         1000000 - 23 members  
  18. //         Jackson :8547741285 ns  
  19. //         FastJSON:15377369425 ns  
  20. //         1000000 - 2 members  
  21. //         Jackson :2581267623 ns  
  22. //         FastJSON:1591827729 ns  
  23.              
  24. //         code only -------------------------------------------------------  
  25. //         10000  - 23 members  
  26. //         Jackson :115036100 ns  
  27. //         FastJSON:158681243 ns  
  28. //         10000  - 2 members  
  29. //         Jackson :87886170 ns  
  30. //         FastJSON:103086025 ns  
  31.              
  32.              
  33. //         100000 - 23 members  
  34. //         Jackson :417539325 ns  
  35. //         FastJSON:349358062 ns  
  36. //         100000 - 2 members   
  37. //         Jackson :185865488 ns  
  38. //         FastJSON:144893485 ns  
  39.              
  40. //         1000000 - 23 members  
  41. //         Jackson :3384171740 ns  
  42. //         FastJSON:2200190119 ns  
  43. //         1000000 - 2 members  
  44. //         Jackson :1193815955 ns  
  45. //         FastJSON:568776506 ns  
  46.              
  47.              
  48. //         decode only -------------------------------------------------------  
  49. //         10000  - 23 members  
  50. //         Jackson :122597862 ns  
  51. //         FastJSON:183567261 ns  
  52. //         10000  - 2 members  
  53. //         Jackson :75418145 ns  
  54. //         FastJSON:47832689 ns  
  55.              
  56.              
  57. //         100000 - 23 members  
  58. //         Jackson :497670344 ns  
  59. //         FastJSON:1254994458 ns  
  60. //         100000 - 2 members   
  61. //         Jackson :165368101 ns  
  62. //         FastJSON:117555618 ns  
  63.              
  64. //         1000000 - 23 members  
  65. //         Jackson :4189147981 ns  
  66. //         FastJSON:12004873228 ns  
  67. //         1000000 - 2 members  
  68. //         Jackson :999578584 ns  
  69. //         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在多成员变量解码时的劣势是什么原因导致的。

付上测试代码:

  1. package jar;  
  2.   
  3. import java.io.StringWriter;  
  4.   
  5. import org.codehaus.jackson.JsonEncoding;  
  6. import org.codehaus.jackson.JsonGenerator;  
  7. import org.codehaus.jackson.map.ObjectMapper;  
  8.   
  9. import com.alibaba.fastjson.JSON;  
  10.   
  11. public class Test{  
  12.       
  13.       
  14.       
  15.     private int aaa=0;  
  16.     private String bbb = "000";  
  17.   
  18.     private String c1 = "000";  
  19.     private String c2 = "000";  
  20.     private String c3 = "000";  
  21.     private String c4 = "000";  
  22.     private String c5 = "000";  
  23.     private String c6 = "000";  
  24.     private String c7 = "000";  
  25.     private String c8 = "000";  
  26.     private String c9 = "000";  
  27.     private String c10 = "000";  
  28.     private String c11 = "000";  
  29.     private String c12 = "000";  
  30.     private String c13 = "000";  
  31.     private String c14 = "000";  
  32.     private String c15 = "000";  
  33.     private String c16 = "000";  
  34.     private String c17 = "000";  
  35.     private String c18 = "000";  
  36.     private String c19 = "000";  
  37.     private String c20 = "000";  
  38.     private String c21 = "000";  
  39.       
  40.       
  41.     public Test()  
  42.     {  
  43.           
  44.     }  
  45.       
  46.       
  47.       
  48.     public Test(int a ,String b) {  
  49.         // TODO Auto-generated constructor stub  
  50.         aaa = a;  
  51.         bbb = b;  
  52.         //System.out.println("construct 2 function is called!!!");  
  53.     }  
  54.       
  55.   
  56.     public int getA() {  
  57.         return aaa;  
  58.     }  
  59.   
  60.   
  61.     public void setA(int a)  
  62.     {  
  63.         this.aaa = a;  
  64.     }  
  65.       
  66.     public String getB() {  
  67.         return bbb;  
  68.     }  
  69.   
  70.     public void setB(String b) {  
  71.         this.bbb = b;  
  72.     }  
  73.       
  74.   
  75.   
  76.     public String getC1() {  
  77.         return c1;  
  78.     }  
  79.   
  80.     public void setC1(String c1) {  
  81.         this.c1 = c1;  
  82.     }  
  83.   
  84.     public String getC2() {  
  85.         return c2;  
  86.     }  
  87.   
  88.     public void setC2(String c2) {  
  89.         this.c2 = c2;  
  90.     }  
  91.   
  92.     public String getC3() {  
  93.         return c3;  
  94.     }  
  95.   
  96.     public void setC3(String c3) {  
  97.         this.c3 = c3;  
  98.     }  
  99.   
  100.     public String getC4() {  
  101.         return c4;  
  102.     }  
  103.   
  104.     public void setC4(String c4) {  
  105.         this.c4 = c4;  
  106.     }  
  107.   
  108.     public String getC5() {  
  109.         return c5;  
  110.     }  
  111.   
  112.     public void setC5(String c5) {  
  113.         this.c5 = c5;  
  114.     }  
  115.   
  116.     public String getC6() {  
  117.         return c6;  
  118.     }  
  119.   
  120.     public void setC6(String c6) {  
  121.         this.c6 = c6;  
  122.     }  
  123.   
  124.     public String getC7() {  
  125.         return c7;  
  126.     }  
  127.   
  128.     public void setC7(String c7) {  
  129.         this.c7 = c7;  
  130.     }  
  131.   
  132.     public String getC8() {  
  133.         return c8;  
  134.     }  
  135.   
  136.     public void setC8(String c8) {  
  137.         this.c8 = c8;  
  138.     }  
  139.   
  140.     public String getC9() {  
  141.         return c9;  
  142.     }  
  143.   
  144.     public void setC9(String c9) {  
  145.         this.c9 = c9;  
  146.     }  
  147.   
  148.     public String getC10() {  
  149.         return c10;  
  150.     }  
  151.   
  152.     public void setC10(String c10) {  
  153.         this.c10 = c10;  
  154.     }  
  155.   
  156.     public String getC11() {  
  157.         return c11;  
  158.     }  
  159.   
  160.     public void setC11(String c11) {  
  161.         this.c11 = c11;  
  162.     }  
  163.   
  164.     public String getC12() {  
  165.         return c12;  
  166.     }  
  167.   
  168.     public void setC12(String c12) {  
  169.         this.c12 = c12;  
  170.     }  
  171.   
  172.     public String getC13() {  
  173.         return c13;  
  174.     }  
  175.   
  176.     public void setC13(String c13) {  
  177.         this.c13 = c13;  
  178.     }  
  179.   
  180.     public String getC14() {  
  181.         return c14;  
  182.     }  
  183.   
  184.     public void setC14(String c14) {  
  185.         this.c14 = c14;  
  186.     }  
  187.   
  188.     public String getC15() {  
  189.         return c15;  
  190.     }  
  191.   
  192.     public void setC15(String c15) {  
  193.         this.c15 = c15;  
  194.     }  
  195.   
  196.     public String getC16() {  
  197.         return c16;  
  198.     }  
  199.   
  200.     public void setC16(String c16) {  
  201.         this.c16 = c16;  
  202.     }  
  203.   
  204.     public String getC17() {  
  205.         return c17;  
  206.     }  
  207.   
  208.     public void setC17(String c17) {  
  209.         this.c17 = c17;  
  210.     }  
  211.   
  212.     public String getC18() {  
  213.         return c18;  
  214.     }  
  215.   
  216.     public void setC18(String c18) {  
  217.         this.c18 = c18;  
  218.     }  
  219.   
  220.     public String getC19() {  
  221.         return c19;  
  222.     }  
  223.   
  224.     public void setC19(String c19) {  
  225.         this.c19 = c19;  
  226.     }  
  227.   
  228.     public String getC20() {  
  229.         return c20;  
  230.     }  
  231.   
  232.     public void setC20(String c20) {  
  233.         this.c20 = c20;  
  234.     }  
  235.   
  236.     public String getC21() {  
  237.         return c21;  
  238.     }  
  239.   
  240.     public void setC21(String c21) {  
  241.         this.c21 = c21;  
  242.     }  
  243.       
  244.       
  245.     //test  
  246.      /** 
  247.      * @param args 
  248.      * @throws Exception 
  249.      */  
  250.     public static void main(String[] args) throws Exception    
  251.      {         
  252.            
  253.             
  254.            Test test =new Test(2,"222");  
  255.              
  256.              
  257.            //JackJSON 初始化  
  258.            ObjectMapper objectMapper = new ObjectMapper();    
  259.            
  260.            long startTime=0;   //获取开始时间  
  261.            long endTime=0//获取结束时间  
  262.              
  263.            int  loopCount  =100000;  
  264.              
  265. //         code + decode -----------------------------------------------------  
  266. //         10000  - 23 members  
  267. //         Jackson :235750737 ns  
  268. //         FastJSON:347795550 ns  
  269. //         10000  - 2 members  
  270. //         Jackson :164173126 ns  
  271. //         FastJSON:159078284 ns  
  272.              
  273.              
  274. //         100000 - 23 members  
  275. //         Jackson :1004902734 ns  
  276. //         FastJSON:1689072614 ns  
  277. //         100000 - 2 members   
  278. //         Jackson :392344461 ns  
  279. //         FastJSON:299521240 ns  
  280.              
  281. //         1000000 - 23 members  
  282. //         Jackson :8547741285 ns  
  283. //         FastJSON:15377369425 ns  
  284. //         1000000 - 2 members  
  285. //         Jackson :2581267623 ns  
  286. //         FastJSON:1591827729 ns  
  287.              
  288. //         code only -------------------------------------------------------  
  289. //         10000  - 23 members  
  290. //         Jackson :115036100 ns  
  291. //         FastJSON:158681243 ns  
  292. //         10000  - 2 members  
  293. //         Jackson :87886170 ns  
  294. //         FastJSON:103086025 ns  
  295.              
  296.              
  297. //         100000 - 23 members  
  298. //         Jackson :417539325 ns  
  299. //         FastJSON:349358062 ns  
  300. //         100000 - 2 members   
  301. //         Jackson :185865488 ns  
  302. //         FastJSON:144893485 ns  
  303.              
  304. //         1000000 - 23 members  
  305. //         Jackson :3384171740 ns  
  306. //         FastJSON:2200190119 ns  
  307. //         1000000 - 2 members  
  308. //         Jackson :1193815955 ns  
  309. //         FastJSON:568776506 ns  
  310.              
  311.              
  312. //         decode only -------------------------------------------------------  
  313. //         10000  - 23 members  
  314. //         Jackson :122597862 ns  
  315. //         FastJSON:183567261 ns  
  316. //         10000  - 2 members  
  317. //         Jackson :75418145 ns  
  318. //         FastJSON:47832689 ns  
  319.              
  320.              
  321. //         100000 - 23 members  
  322. //         Jackson :497670344 ns  
  323. //         FastJSON:1254994458 ns  
  324. //         100000 - 2 members   
  325. //         Jackson :165368101 ns  
  326. //         FastJSON:117555618 ns  
  327.              
  328. //         1000000 - 23 members  
  329. //         Jackson :4189147981 ns  
  330. //         FastJSON:12004873228 ns  
  331. //         1000000 - 2 members  
  332. //         Jackson :999578584 ns  
  333. //         FastJSON:863444723 ns  
  334.              
  335.            //Jackson  
  336.             
  337.             
  338.            startTime =  System.nanoTime();  
  339.            
  340.            for(int i=0;i<loopCount;i++)  
  341.            {  
  342.                StringWriter sw = new StringWriter();  
  343.                JsonGenerator jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(sw);  
  344.                jsonGenerator.writeObject(test);   
  345.                String result = sw.toString();  
  346.               // Test acc = objectMapper.readValue(result, Test.class);   
  347.            }  
  348.            endTime =  System.nanoTime();  
  349.            System.out.println("Jackson :"+(endTime-startTime)+" ns");  
  350.   
  351.              
  352.             
  353.            startTime =  System.nanoTime();  
  354.            //FastJSON  
  355.            for(int i=0;i<loopCount;i++)  
  356.            {  
  357.                String code =  JSON.toJSONString(test);  
  358.              // Test reverse = JSON.parseObject(code,Test.class);  
  359.            }  
  360.            endTime =  System.nanoTime();  
  361.   
  362.            System.out.println("FastJSON:"+(endTime-startTime)+" ns");  
  363.       
  364.      }  
  365.   
  366. }  


还有一篇TS回复挑战者的基准测试结果的文章,虽然和本文没有直接关系,但是反映了一些东西。可以了解了解。

http://www./cn/news/2014/05/jackson-founder-responds



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多