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。

對於這個問題,你有什麼見解,歡迎留言評論。


分享到:


相關文章: