1. 程式人生 > >兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)

兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)

border word ogg 收藏 一個 gen 每次 應用 googl

本篇文章主要介紹了"兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)",主要涉及到兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)方面的內容,對於兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)感興趣的同學可以參考一下。

近日做一些性能優化工作,在挑選JSON類庫時,發現除了一般常用的JSON-lib外,還有一款號稱性能最快的JSON處理器Jackson,於是用上了剛學會的JMeter,對這兩個類庫進行了簡單的性能對比。

Jackson:http://jackson.codehaus.org/

JSON-lib:http://json-lib.sourceforge.net/

Gson:http://code.google.com/p/google-gson/

測試環境:

1、工作電腦:Intel雙核E8400 共6GHz,內存4GB,WinXP

2、JSON-lib用最新的JDK15,GSON版本是最新的v1.4,Jackson也是最新的v1.5.5,JDK-v1.6.0_20,JMeter-v2.4

3、測試時不開啟任何無關進程,每完成一項測試後關閉JMeter整理內存後,再進行下一項測試,每項測試運行3次,取平均值

4、JSON轉Java Bean意為將JSON格式轉換成Java類,這個類內包括Map、List、Date、Integer/Long/Double、String等類型的屬性,Java Bean轉Json則同理。另外,兩者互轉,每次轉換的數據都是隨機生成

測試結果:

* 吞吐量的值越大越好,總耗時的值越小越好

JSON轉Bean,5個線程並發,約200字節對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 64113.7 8067.4 13952.8
總耗時(秒) 155 1238 700

Bean轉JSON,5個線程並發,約200字節對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 54802 15093.2 17308.2
總耗時(秒) 181 661 560

JSON轉Bean,5個線程並發,約2K對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 37314 2406.9 3657.50
總耗時(秒) 267 4120 2720

Bean轉JSON,5個線程並發,約2K對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 30922.2 4274.8 4977.00
總耗時(秒) 322 2320 2000

測試總結:

1、顯而易見,無論是哪種形式的轉換,Jackson > Gson > Json-lib。

Jackson的處理能力甚至高出Json-lib有10倍左右

2、JSON-lib似乎已經停止更新,最新的版本也是基於JDK15,而Jackson的社區則較為活躍;

3、在測試性能的同時,又以人肉方式對這三個類庫轉換的正確性 進行了檢查 ,三者均達100%正確

4、JSON-lib在轉換諸如Date類型時較為累贅,如以下是兩者的轉換結果:

JSON-lib:

{"brithday":{"date":17,"day":2,"hours":9,"minutes":24,"month":7,"seconds":26,"time":1282008266398,"timezoneOffset":-480,"year":110}}

Jackson:

{"brithday":1282008123101}

5、JSON-lib依賴commons系列的包及 ezmorph包共 5個,而Jackson除自身的以外只依賴於commons-logging
6、Jackson提供完整基於節點的Tree Model,以及完整的OJM數據綁定功能。

Jackson使用示例:

JacksonMapper:

創建為餓漢式單例模式 ,Jackson用於轉換的核心類ObjectMapper無需每次都new一個object,官網上的一句話:can reuse, share globally

Java代碼 技術分享
  1. /**
  2. * @author xuanyin
  3. *
  4. */
  5. public class JacksonMapper {
  6. /**
  7. *
  8. */
  9. private static final ObjectMapper mapper = new ObjectMapper();
  10. /**
  11. *
  12. */
  13. private JacksonMapper() {
  14. }
  15. /**
  16. *
  17. * @return
  18. */
  19. public static ObjectMapper getInstance() {
  20. return mapper;
  21. }
  22. }

JSON轉Bean:

Java代碼 技術分享
  1. ......
  2. String json = "...";
  3. ObjectMapper mapper = JacksonMapper.getInstance();
  4. YourBean bean = mapper.readValue(json, new YourBean().getClass());
  5. ......

Bean轉JSON:

Java代碼 技術分享
  1. ......
  2. YourBean bean = new YourBean();
  3. ......
  4. ObjectMapper mapper = JacksonMapper.getInstance();
  5. StringWriter sw = new StringWriter();
  6. JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
  7. mapper.writeValue(gen, bean);
  8. gen.close();
  9. String json = sw.toString();
  10. ......

* 上面兩段代碼中的YourBean當然也可以是Java的基本類型

近日做一些性能優化工作,在挑選JSON類庫時,發現除了一般常用的JSON-lib外,還有一款號稱性能最快的JSON處理器Jackson,於是用上了剛學會的JMeter,對這兩個類庫進行了簡單的性能對比。

Jackson:http://jackson.codehaus.org/

JSON-lib:http://json-lib.sourceforge.net/

Gson:http://code.google.com/p/google-gson/

測試環境:

1、工作電腦:Intel雙核E8400 共6GHz,內存4GB,WinXP

2、JSON-lib用最新的JDK15,GSON版本是最新的v1.4,Jackson也是最新的v1.5.5,JDK-v1.6.0_20,JMeter-v2.4

3、測試時不開啟任何無關進程,每完成一項測試後關閉JMeter整理內存後,再進行下一項測試,每項測試運行3次,取平均值

4、JSON轉Java Bean意為將JSON格式轉換成Java類,這個類內包括Map、List、Date、Integer/Long/Double、String等類型的屬性,Java Bean轉Json則同理。另外,兩者互轉,每次轉換的數據都是隨機生成

測試結果:

* 吞吐量的值越大越好,總耗時的值越小越好

JSON轉Bean,5個線程並發,約200字節對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 64113.7 8067.4 13952.8
總耗時(秒) 155 1238 700

Bean轉JSON,5個線程並發,約200字節對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 54802 15093.2 17308.2
總耗時(秒) 181 661 560

JSON轉Bean,5個線程並發,約2K對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 37314 2406.9 3657.50
總耗時(秒) 267 4120 2720

Bean轉JSON,5個線程並發,約2K對象,1千萬次轉換:

Jackson JSON-lib Gson
TPS 30922.2 4274.8 4977.00
總耗時(秒) 322 2320 2000

測試總結:

1、顯而易見,無論是哪種形式的轉換,Jackson > Gson > Json-lib。

Jackson的處理能力甚至高出Json-lib有10倍左右

2、JSON-lib似乎已經停止更新,最新的版本也是基於JDK15,而Jackson的社區則較為活躍;

3、在測試性能的同時,又以人肉方式對這三個類庫轉換的正確性 進行了檢查 ,三者均達100%正確

4、JSON-lib在轉換諸如Date類型時較為累贅,如以下是兩者的轉換結果:

JSON-lib:

{"brithday":{"date":17,"day":2,"hours":9,"minutes":24,"month":7,"seconds":26,"time":1282008266398,"timezoneOffset":-480,"year":110}}

Jackson:

{"brithday":1282008123101}

5、JSON-lib依賴commons系列的包及ezmorph包共5個,而Jackson除自身的以外只依賴於commons-logging
6、Jackson提供完整基於節點的Tree Model,以及完整的OJM數據綁定功能。

Jackson使用示例:

JacksonMapper:

創建為餓漢式單例模式 ,Jackson用於轉換的核心類ObjectMapper無需每次都new一個object,官網上的一句話:can reuse, share globally

Java代碼
  1. /**
  2. * @author xuanyin
  3. *
  4. */
  5. public class JacksonMapper {
  6. /**
  7. *
  8. */
  9. private static final ObjectMapper mapper = new ObjectMapper();
  10. /**
  11. *
  12. */
  13. private JacksonMapper() {
  14. }
  15. /**
  16. *
  17. * @return
  18. */
  19. public static ObjectMapper getInstance() {
  20. return mapper;
  21. }
  22. }

JSON轉Bean:

Java代碼
  1. ......
  2. String json = "...";
  3. ObjectMapper mapper = JacksonMapper.getInstance();
  4. YourBean bean = mapper.readValue(json, new YourBean().getClass());
  5. ......

Bean轉JSON:

Java代碼
  1. ......
  2. YourBean bean = new YourBean();
  3. ......
  4. ObjectMapper mapper = JacksonMapper.getInstance();
  5. StringWriter sw = new StringWriter();
  6. JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
  7. mapper.writeValue(gen, bean);
  8. gen.close();
  9. String json = sw.toString();
  10. ......

* 上面兩段代碼中的YourBean當然也可以是Java的基本類型

文章不足之處歡迎大家留言指正:)

11 樓 wangym 2010-08-18 引用 wangliang_5290 寫道 wangym 寫道 wangliang_5290 寫道 我碰到一個問題,要將字符串
String json = "{a:1, b:2}";
轉化為 Map, 如果用Jackson的話,對字符串格式有嚴格要求,必須為
String json = "{\"a\":1, \"b\":2}";
否則報錯,覺得不爽。

不知道是對Json了解不夠呢, 還是Jackson就是這麽要求的?



在JAVA裏定義這樣一個String自然是需要"\"給後面的引號進行轉義,無論是用哪個JSON類庫都一樣,但在實際應用中,沒有這個問題。

實際應用中json串不一定是在java中定義的,有可能是從頁面傳過來的,java只是負責解析。我以前用的是json-lib沒有問題, 但是換成jackson後出現這個問題。不知道是不是對jackson的API研究不夠?
1.json-lib 以下寫法沒有問題
Java代碼
  1. Map map = JSONObject.fromObject("{a:1, b:2}");

2.jackson 以下寫法報異常
Java代碼
  1. Map map = new ObjectMapper().readValue("{a:1, b:2}", HashMap.class);
必須寫成
Java代碼
  1. Map map = new ObjectMapper().readValue("{\"a\":1, \"b\":2}", HashMap.class);


不好意思一開始沒明白你的意思
請開啟支持字段名稱不帶引號的轉換模式,默認是關閉的.
即將上面報異常的那句改成這樣: Java代碼
  1. Map map = new ObjectMapper().configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true).readValue("{a:1, b:2}", HashMap.class);

24 樓 wangym 2011-01-18 引用 JSON轉POJO時,若JSON中的某個字段在POJO中未定義,在默認情況下會拋異常轉換失敗,只要增加這個配置:
Java代碼
    1. Feature.FAIL_ON_UNKNOWN_PROPERTIES, false
      就可以轉換正常,即只轉換定義的字段,未定義的字段忽略。

兩款JSON類庫Jackson與JSON-lib的性能對比(新增第三款測試)