JSON不管是在Web開發還是服務器開發中是相當常見的數據傳輸格式,一般情況我們對於JSON解析構造的性能並不需要過於關心,除非是在性能要求比較高的系統。
目前對於Java開源的JSON類庫有很多種,下面我們取三個常用的JSON庫進行性能測試對比,同時根據測試結果分析如果根據實際應用場景選擇最合適的JSON庫。
四個JSON類庫分別為:Gson,FastJson,Jackson,Json-lib。
簡單介紹下四個類庫的身份背景。
- Gson(項目地址:https://github.com/google/gson)
- Gson是目前功能最全的Json解析神器,Gson當初是為因應Google公司內部需求而由Google自行研發而來,但自從在2008年五月公開發布第一版后已被許多公司或用戶應用。Gson的應用主要為toJson與fromJson兩個轉換函數,無依賴,不需要例外額外的jar,能夠直接跑在JDK上。而在使用這種對象轉換之前需先創建好對象的類型以及其成員才能成功的將JSON字符串成功轉換成相對應的對象。類里面只要有get和set方法,Gson完全可以將復雜類型的json到bean或bean到json的轉換,是JSON解析的神器。
- FastJson(項目地址:https://github.com/alibaba/fastjson)
- Fastjson是一個Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發。無依賴,不需要例外額外的jar,能夠直接跑在JDK上。FastJson在復雜類型的Bean轉換Json上會出現一些問題,可能會出現引用的類型,導致Json轉換出錯,需要制定引用。FastJson采用獨創的算法,將parse的速度提升到極致,超過所有json庫。
- Jackson(項目地址:https://github.com/FasterXML/jackson)
- 相比json-lib框架,Jackson所依賴的jar包較少,簡單易用並且性能也要相對高些。而且Jackson社區相對比較活躍,更新速度也比較快。Jackson對於復雜類型的json轉換bean會出現問題,一些集合Map,List的轉換出現問題。Jackson對於復雜類型的bean轉換Json,轉換的json格式不是標准的Json格式。
- Json-lib(項目地址:http://json-lib.sourceforge.net/index.html)
- json-lib最開始的也是應用最廣泛的json解析工具,json-lib 不好的地方確實是依賴於很多第三方包,包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,對於復雜類型的轉換,json-lib對於json轉換成bean還有缺陷,比如一個類里面會出現另一個類的list或者map集合,json-lib從json到bean的轉換就會出現問題。json-lib在功能和性能上面都不能滿足現在互聯網化的需求。
選擇一個合適的JSON庫要從多個方面進行考慮:
- 字符串解析成JSON性能
- 字符串解析成JavaBean性能
- JavaBean構造JSON性能
- 集合構造JSON性能
- 易用性
對於前四條其實都是從JSON的解析構造性能角度考慮,而最后一條則是考慮易用性,這點對於開發者來說其實也是需要考慮的一個問題,如果該庫的API使用難度大,或者很復雜,那么不建議使用,畢竟JSON解析的性能差異並不大。下面的測試結果針對四個不同數量級的JSON字符串,以及分別測試上面提到的前四條性能,結果如下:
Json-lib在數據量在10W時OOM了,內存開到1G都不行,所以直接Pass了。
從上面圖表可以看到:
- 字符串解析成JavaBean:當數據量較少時首選FastJson,數據量較大使用Jackson。但是Jackson無法堆一個對象集合進行解析,只能轉成一個Map集合,這點Gson和FastJson處理的比較好。
- 字符串解析成JSON:當數據量較少時首選FastJson,數據量較大使用Jackson。
- JavaBean構造JSON:當數據量較少時選擇Gson,數據量較大可使用Jackson。
- 集合構造JSON:首先Jackson,其次Fastjson。
上面是從性能角度分析四種JSON類庫,從易用性角度來分析的話,FastJson的API設計的最簡單,最方便使用,直接使用JSON的兩個靜態方法即可完成四種操作;而Gson和Jackson都需要new一個對象,雖然這個對象可以復用,但是在實際使用過程中還需要用一個全局變量來保存改變量,同時API設計的也不是很好理解,對於FastJson來說復雜的API是因為他支持流式解析,適合對JSON進行大量且復雜的操作,但是實際應用中對於JSON的操作都是簡單的解析成JavaBean,然后JavaBean序列化成JSON字符串即可,復雜的操作很少。
下面從我自己實際的應用場景出發,考慮該如何選擇合適的JSON類庫。
應用場景:游戲服務器,基本是對客戶端發送過來的JSON格式字符串解析成JavaBean,然后將封裝好的指令轉成JSON字符串返回給客戶端,這里考慮到JavaBean轉成JSON與集合轉成JSON的性能差異,所以直接使用集合進行轉成JSON,避免使用JavaBean。
考慮上述場景適合使用FastJson進行JSON字符串解析,Jackson將集合轉成JSON格式字符串。
淺嘗輒止,歡迎批評指出。