当前位置 博文首页 > 文章内容

    看图说话,FastJson 并没有那么流行!

    作者: 栏目:未分类 时间:2020-08-28 15:01:26

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    作者:咔咔侃技术

    来源:www.toutiao.com/i6815906868183958027

    一、FastJson为何

    首先抄录一段来自官网的介绍:FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。

    FastJson是Java程序员常用到的类库之一,相信点开这个页面的你,也肯定是程序员朋友。正如其名,“快”是其主要卖点。

    二、真的很快吗?

    没有调研就没有发言权,本着“追求真理”的初心,来一轮简单的测试。对比对象选择应用最广泛的Jackson和Google出品的Gson。

    测试环境选择JDK 8,AMD 3700X,3200MHZ内存。简化实验,只测试简单对象和复杂对象的String转对象、对象转String,调用1千万次的对比结果如下(时间单位是毫秒):

    从测试结果看,FastJson确实是最快的,但仅比Jackson快20%左右,Google的Gson是最慢的,差距较大。读到这里,是不是觉得选择FastJson肯定没错啊!

    如果面试官问为什么选择FastJson?因为快!这一个理由就可以把他顶回去了。

    这里的调查研究并不是很充分,没有对内存占用、大文档的测试。

    在现代应用程序中,即使最慢的Gson,也是满足需求的;解析文档速度的快慢,并不能作为选型的唯一标准,可能连主要标准都算不上。对IO优化,并行处理等优化措施,比选用一个更快的库更有效。

    三、FastJson并没有那么流行

    然而,FastJson并没有那么流行,有一个最直观的数据,那就是在Maven的中的引用量,和Jackson和Gson不在一个数量级,和Jackson强大的家族更没法比。

    难道我用了一个假的流行的国产类库?在知乎看到了一篇帖子,讨论为什么外国友人不喜欢FastJson。

    结论就是FastJson是个代码质量不高的国产类库。完全颠覆了我的认知,因为在我的项目中,是经常使用FastJson的,并没有出现什么Bug,而且这段评论是在2016年写的。

    抱着怀疑的态度,打开FastJson的地址,看到大家提的Issues。竟然有1283个未解决的Issues。红框标识出来的,我自己拿去研究下,因为我看到下面还有人提了一样的问题。

    测试代码如下:

     try {
          String time = "1970-01-01 00:00:00";
          com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
          jsonObject.put("time", time);
    
          Timestamp timestamp = jsonObject.getTimestamp("time");
          System.out.println("time:" + timestamp);
      } catch (Exception e) {
          e.printStackTrace();
      }
    

    果然,在采用了最新版本的类库后,如问题描述的,还是有异常。于是就看到了如下的源代码:

    if (strVal.endsWith(".000000000")) {
        strVal = strVal.substring(0, strVal.length() - 10);
    } else if (strVal.endsWith(".000000")) {
        strVal = strVal.substring(0, strVal.length() - 7);
    }
    
    if (strVal.length() == 29 && strVal.charAt(4) == '-' && strVal.charAt(7) == '-' && strVal.charAt(10) == ' ' && strVal.charAt(13) == ':' && strVal.charAt(16) == ':' && strVal.charAt(19) == '.') {
        int year = num(strVal.charAt(0), strVal.charAt(1), strVal.charAt(2), strVal.charAt(3));
        int month = num(strVal.charAt(5), strVal.charAt(6));
        int day = num(strVal.charAt(8), strVal.charAt(9));
        int hour = num(strVal.charAt(11), strVal.charAt(12));
        int minute = num(strVal.charAt(14), strVal.charAt(15));
        int second = num(strVal.charAt(17), strVal.charAt(18));
        int nanos = num(strVal.charAt(20), strVal.charAt(21), strVal.charAt(22), strVal.charAt(23), strVal.charAt(24), strVal.charAt(25), strVal.charAt(26), strVal.charAt(27), strVal.charAt(28));
      return new Timestamp(year - 1900, month - 1, day, hour, minute, second, nanos);
    }
    

    这段代码有严重的逻辑错误,这样错误的格式,例如:

    “1970-01-01 00:00:00.000000000.000000000”

    或者

    “1970-01-01 00:00:00.000000000.000000”

    也能转换成功,而一些正确的格式,例如:

    “1970-01-01 00:00:00”,“1970-01-01 00:00:00.000”

    却转换失败。

    结合网友的点评,我本人也觉得FastJson并没有那么优秀,另一些深入的点评,例如ASM,我的理解并不深,就不做测试了。

    四、弃坑fastjson

    在我负责的项目中,因为Spring Boot相关的框架中,应用了Jackson,本着“最少依赖”的原则,json解析应用了Jackson。但是很多同事的代码中,也用了Gson和Fastjson,当然,是没有严格规范要求的结果。

    通过今天的一个小小研究,Jackson的流行,是有着内在的原因的。在我们以后的项目中,主推Jackson,逐渐的淘汰Fastjson。

    推荐去我的博客阅读更多:

    1.Java JVM、集合、多线程、新特性系列教程

    2.Spring MVC、Spring Boot、Spring Cloud 系列教程

    3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

    4.Java、后端、架构、阿里巴巴等大厂最新面试题

    觉得不错,别忘了点赞+转发哦!