FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

FastJson为何物

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

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

FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

真的很快吗?

没有调研就没有发言权,本着“追求真理”的初心,来一轮简单的测试。对比对象选择应用最广泛的Jackson和Google出品的Gson。测试环境选择JDK 8,AMD 3700X,3200MHZ内存。简化实验,只测试简单对象和复杂对象的String转对象、对象转String,调用1千万次的对比结果如下(时间单位是毫秒):

FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

从测试结果看,FastJson确实是最快的,但仅比Jackson快20%左右,Google的Gson是最慢的,差距较大。读到这里,是不是觉得选择FastJson肯定没错啊!如果面试官问为什么选择FastJson?因为快!这一个理由就可以把他顶回去了。

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

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

FastJson并没有那么流行

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


FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

难道我用了一个假的流行的国产类库?在知乎看到了一篇帖子,讨论为什么外国友人不喜欢FastJson。结论就是FastJson是个代码质量不高的国产类库。完全颠覆了我的认知,因为在我的项目中,是经常使用FastJson的,并没有出现什么Bug,而且这段评论是在2016年写的。

FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

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

FastJSON、Jackson、Gson怎么选?反正我不推荐FastJson

测试代码如下:

<code>    

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(); }/<code>

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

<code>

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); } /<code>

这段代码有严重的逻辑错误,这样错误的格式,例如:“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

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

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

对于这个问题,你有什么见解,欢迎留言评论。


分享到:


相關文章: