json-lib和jackson進行Java對象到json字符串序列化性能比較

轉自http://www.javaeye.com/topic/561368
網上查找“java json”,發現大家使用最多的還是json-lib來進行java對象的序列化成json對象和反序列化成java對象的操作。但是之前在網上也看到過一往篇關於json序列化性能比較的文章,不過一下子找不到了,所以沒有引用。另外公司同事也做過類似的測試,結果都表明,json-lib的性能不太令人滿意,而一個叫jackson的json序列化工具卻表現不俗,另外,json-lib對null值的處理讓人也感覺比較困惑。
    這裏,我也對這兩個java json工具進行了一次粗略的測試,主要測試從java對象序列化成json字符串的性能。按以下三種方式進行:
  1. 使用jackson,並在每次循環中重用ObjectMapper對象(jackson with cache)
  2. 使用jackson,並在每次循環中重新生成ObjectMapper對象(jackson without cache)
  3. 使用json-lib
  4. 直接使用StringBuffer進行字符串拼接
    因爲見過有人在使用jackson時,每次都new 一個ObjectMapper的情況,而在官方教程中看到過這樣一段話(can reuse, share globally)http://jackson.codehaus.org/Tutorial
Java代碼 
  1. ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally   
  2. User user = mapper.readValue(new File("user.json"), User.class);  
即ObjectMapper可以重用,所以這裏同時進行重用和不重用方式的測試,另外還測試直接使用StringBuffer拼接字符串的方式,以比較json序列化與原始的java方法的性能差異。
    這裏以不斷增加併發線程數,每個線程循環進行1000次序列化,每次進行100次測量,結果取一個線程跑完(即序列化完1000次)的時間平均值的方式測試在多線程併發情況下的性能。
  1. 測量次數 = 100  
  2. 每個線程循環進行序列化次數 = 1000  
  3. 平均時間爲一個線程跑完時間 = 總時間/測量次數/線程數 
    測試的java對象包含了基本類型屬性和複雜屬性,並且對象具有繼承關係




注:內存使用情況的數據據僅供參考,這個結果並不準確,因爲受機器影響比較大,每次測試差異也比較大,不能準確說明問題,但還是可以參考一下。
  1. 從上面的兩個時間性能的圖中可以看出,無論是在低併發還是高併發的情況下,時間性能上,jackson使用重用ObjectMapper方式大大優於使用json-lib方式,甚於jackson使用非重用ObjectMapper方式也略優於json-lib方式。另外也可以看出,jackson在重用ObjectMapper的方式下,性能幾乎接近於直接使用StringBuffer的append方法拼接了,尤其在高併發的情況下,兩者的曲線幾乎要重合了。從這裏可以看出jackson的性能非常出色。   
  2. 另外,從兩個空間性能的圖中得出的結論與時間性能基本相同,但是由於內存的使用量波動較大,每次測量的結果也相差比較大,並不十分準確,但還是可以看出個大概。   
  3. 此外,還發現一個現象,在低線程數的情況下,只開一個線程的時間性能要比同時開多個線程的時間性能差不少,具體原因還有待分析,不知道是否與雙核CPU有關。  
    另外附上測試代碼json-test.rar,其中使用了一個同事寫的測試工具,叫nanobench.jar的jar包(這個工具會在每次測試前每做一次“預熱”,以排除干擾,因爲java虛擬機剛開始運行時會比較慢。並在測試前會做機器資源清理工作,以減小每次測試受上次測試的影響,參考源碼:http://code.google.com/p/nanobench/source/checkout)。

注意:
1.gson比jackson慢一個數量級,而且gson是對field序列化,不符合java bean慣例對getter序列化.
2.一個複雜對象序列化1000次,我用jackson花了6.5ms,而用gson花了65ms左右
3.json-lib與struts2帶的json插件相比也要慢30%,性能確實一般。
4.xstream序列化也對javabean的規範支持不好,不是根據get方法來的,是根據屬性來的。
5.更詳細的benchmark,詳細比較了各種序列化機制的性能
http://wiki.github.com/eishay/jvm-serializers/
6.XStream本身並不提供JSON序列化的工具,但是它本身又支持JSON和Java Object之間的轉換,是通過Jettison來完成的。
7.這個例子有點小問題啊,ObjectWrapper是在一個線程裏公用的,不是在多個線程間公用的,一般高併發的話應該是要再多個線程間公用吧,那這個時候ObjectWrapper是線程安全的嗎
8.更正確的做法是要在不同線程中公用,這樣測出的性能應該更高。 另外這個ObjectMapper在官方文檔上有說明,這個是線程安全的。
發佈了34 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章