一、背景

有项目需要传输Map结构的数据,有人倾向用Java序列化来做,有人倾向用JSON的序列化来做。所以我们还是比比吧。

Java观点:Object2Object,使用时简单快速。

JSON观点:JSON格式与语言无关,扩展性强,速度也应该不慢。

大家可能对Java序列化都有一个错误的认识,认为Java序列化比JSON的序列化效率高并且序列化的数据小,其实实际上并不一定是这样,我这次就想通过实际测试来解开这个谜团。

二、测试方式

测试同一个Map<String,Object>并序列化为byte[],并再将byte[]反序列化为Map<String,Object>的过程。Object中包括String,Integer,Long,Boolean,Float,Double常规类型的数据。

序列化:Map<String,Object> -> byte[]

byte[] -> Map<String,Object>

测试各种大小不同的Map,并循环执行同一操作N次,来得到一个相对稳定的线性结果。

三、比较的对象

JAVA:

手写Java(1.6.0_32)与Common Lang3(3.1)的SerializationUtils。

JSON:

将采用Gson(2.2.2)与json-smart(2.0-RC2)两种不同的JSON解析器。json-smart号称是速度最快的JSON解析器。

四、比较结果

Map大小(10-100)循环10万次

序列化时间比较(y为序列化时间ms)

Java类JSON序列化 java序列化与json_Java

反序列化时间比较(y为反序列化时间ms)

Java类JSON序列化 java序列化与json_序列化_02

序列化时间汇总比较(y为序列化与反序列化总时间ms)

Java类JSON序列化 java序列化与json_Java类JSON序列化_03

序列化后byte大小比较(由于同类线重合显示为2条线)

Java类JSON序列化 java序列化与json_Java_04

Map大小(100-1000)循环1万次

序列化时间比较(y为序列化时间ms)

Java类JSON序列化 java序列化与json_Java类JSON序列化_05

反序列化时间比较(y为反序列化时间ms)

Java类JSON序列化 java序列化与json_Java类JSON序列化_06

序列化时间汇总比较(y为序列化与反序列化总时间ms)

Java类JSON序列化 java序列化与json_序列化_07

序列化后byte大小比较(由于同类线重合显示为2条线)

Java类JSON序列化 java序列化与json_Java_08

比较总结

Map在小于100时:
Java的反序列化时的性能要比Java序列化时性能差很多,1.5倍左右差距。
JSON序列化性能明显由于Java序列化性能,尤其是反序列化过程。并且序列化后的数据大小也是JSON格式的小。

Map在大于100小于1000时:
Java的反序列化时的性能并没有随Map的大小变化而变差。
JSON阵营中Gson在序列化过程中,比Java只快了那么一点点。在反序列化过程中Gson开始领先与Java,但在Map的大小过700多以后,Gson的反序列化性能比Java要慢。但JSON阵营中的json-smart依然表现出色完全是两个级别。

的格式,稳定简单的数据结构大大简化了序列化过程,虽然也要创建新的Java数据对象但并不会比Java反序列化的速度慢。

从测试结果上看JSON的json-smart更适合项目的需要。

五、测试代码源码

SerializationTest接口

package          org.noahx.javavsjson;        


                  


         import          java.util.Map;        


                  


         /**        


                  * Created with IntelliJ IDEA.        


                  * User: noah        


                  * Date: 3/8/13        


                  * Time: 9:59 PM        


                  * To change this template use File | Settings | File Templates.        


                  */        


         public          interface          SerializationTest {        


                  


                  public          String getTestName();        


                  


                  public          Map<String, Object> testBytes2Map(         byte         [] bytes);        


                  


                  public          byte         [] testMap2Bytes(Map<String, Object> map);        


         }






JavaSerializationTest

package          org.noahx.javavsjson;        


                  


         import          java.io.*;        


         import          java.util.Map;        


                  


         /**        


                  * Created with IntelliJ IDEA.        


                  * User: noah        


                  * Date: 3/8/13        


                  * Time: 10:05 PM        


                  * To change this template use File | Settings | File Templates.        


                  */        


         public          class          JavaSerializationTest          implements          SerializationTest {        


                  


                  @Override        


                  public          String getTestName() {        


                  return          "Java"         ;        


                  }        


                  


                  @Override        


                  public          Map<String, Object> testBytes2Map(         byte         [] bytes) {        


                  Map<String, Object> result =          null         ;        


                  try          {        


                  ByteArrayInputStream byteArrayInputStream =          new          ByteArrayInputStream(bytes);        


                  ObjectInputStream inputStream =          new          ObjectInputStream(byteArrayInputStream);        


                  


                  result = (Map<String, Object>) inputStream.readObject();        


                  inputStream.close();        


                  }          catch          (ClassNotFoundException e) {        


                  e.printStackTrace();        


                  }          catch          (IOException e) {        


                  e.printStackTrace();        


                  }        


                  


                  return          result;        


                  }        


                  


                  @Override        


                  public          byte         [] testMap2Bytes(Map<String, Object> map) {        


                  byte         [] bytes =          null         ;        


                  try          {        


                  ByteArrayOutputStream byteArrayOutputStream =          new          ByteArrayOutputStream();        


                  ObjectOutputStream outputStream =          new          ObjectOutputStream(byteArrayOutputStream);        


                  


                  outputStream.writeObject(map);        


                  outputStream.close();        


                  


                  bytes = byteArrayOutputStream.toByteArray();        


                  }          catch          (IOException e) {        


                  e.printStackTrace();        


                  }        


                  return          bytes;        


                  }        


         }






CommonLang3SerializationTest


package          org.noahx.javavsjson;        


                  


         import          org.apache.commons.lang3.SerializationUtils;        


                  


         import          java.io.Serializable;        


         import          java.util.Map;        


                  


         /**        


                  * Created with IntelliJ IDEA.        


                  * User: noah        


                  * Date: 3/9/13        


                  * Time: 2:24 AM        


                  * To change this template use File | Settings | File Templates.        


                  */        


         public          class          CommonLang3SerializationTest          implements          SerializationTest {        


                  @Override        


                  public          String getTestName() {        


                  return          "Commons Lang3"         ;        


                  }        


                  


                  @Override        


                  public          Map<String, Object> testBytes2Map(         byte         [] bytes) {        


                  return          (Map<String, Object>) SerializationUtils.deserialize(bytes);        


                  }        


                  


                  @Override        


                  public          byte         [] testMap2Bytes(Map<String, Object> map) {        


                  return          SerializationUtils.serialize((Serializable) map);        


                  }        


         }






GsonSerializationTest


package          org.noahx.javavsjson;        


                  


         import          com.google.gson.Gson;        


                  


         import          java.io.UnsupportedEncodingException;        


         import          java.util.Map;        


                  


         /**        


                  * Created with IntelliJ IDEA.        


                  * User: noah        


                  * Date: 3/8/13        


                  * Time: 10:02 PM        


                  * To change this template use File | Settings | File Templates.        


                  */        


         public          class          GsonSerializationTest          implements          SerializationTest {        


                  


                  private          Gson gson;        


                  


                  public          GsonSerializationTest() {        


                  gson =          new          Gson();        


                  }        


                  


                  @Override        


                  public          String getTestName() {        


                  return          "Gson"         ;        


                  }        


                  


                  @Override        


                  public          Map<String, Object> testBytes2Map(         byte         [] bytes) {        


                  Map<String, Object> result =          null         ;        


                  try          {        


                  result = gson.fromJson(         new          String(bytes,          "UTF-8"         ), Map.         class         );        


                  }          catch          (UnsupportedEncodingException e) {        


                  e.printStackTrace();        


                  }        


                  return          result;        


                  }        


                  


                  @Override        


                  public          byte         [] testMap2Bytes(Map<String, Object> map) {        


                  String str = gson.toJson(map);        


                  byte         [] bytes =          null         ;        


                  try          {        


                  bytes = str.getBytes(         "UTF-8"         );        


                  }          catch          (UnsupportedEncodingException e) {        


                  e.printStackTrace();        


                  }        


                  return          bytes;        


                  }        


         }






JsonSmartSerializationTest


package          org.noahx.javavsjson;        


                  


         import          net.minidev.json.JSONObject;        


         import          net.minidev.json.JSONValue;        


         import          net.minidev.json.parser.ParseException;        


                  


         import          java.io.UnsupportedEncodingException;        


         import          java.util.Map;        


                  


         /**        


                  * Created with IntelliJ IDEA.        


                  * User: noah        


                  * Date: 3/9/13        


                  * Time: 1:30 AM        


                  * To change this template use File | Settings | File Templates.        


                  */        


         public          class          JsonSmartSerializationTest          implements          SerializationTest {        


                  @Override        


                  public          String getTestName() {        


                  return          "Json Smart"         ;        


                  }        


                  


                  @Override        


                  public          Map<String, Object> testBytes2Map(         byte         [] bytes) {        


                  Map<String, Object> map =          null         ;        


                  try          {        


                  map = (Map<String, Object>) JSONValue.parseStrict((         new          String(bytes,          "UTF-8"         )));        


                  }          catch          (ParseException e) {        


                  e.printStackTrace();        


                  }          catch          (UnsupportedEncodingException e) {        


                  e.printStackTrace();        


                  }        


                  return          map;        


                  }        


                  


                  @Override        


                  public          byte         [] testMap2Bytes(Map<String, Object> map) {        


                  String str = JSONObject.toJSONString(map);        


                  byte         [] result =          null         ;        


                  try          {        


                  result = str.getBytes(         "UTF-8"         );        


                  }          catch          (UnsupportedEncodingException e) {        


                  e.printStackTrace();        


                  }        


                  return          result;        


                  }        


         }




源码下载:http://sdrv.ms/12ECmgG


P.S.

我也测试过Map<String,String>固定数据类型value只为String的情况,这时Java与JSON的性能的差距会减小,但JSON序列化性能与数据大小还是占优势,尤其是反序列化的速度JSON更出色。

Gson在数值反序列化后,因为Object无法确定类型,Map中的Long,Integer,Float统一转为了Double类型。
json-smart不一样,如果整数超过Integer的范围转Long,没有超过转Integer。浮点Float转为Double类型。