有项目须要传输Map结构的数据,有人倾向用Java序列化来作,有人倾向用JSON的序列化来作。因此咱们仍是比比吧。 java
Java观点:Object2Object,使用时简单快速。 apache
JSON观点:JSON格式与语言无关,扩展性强,速度也应该不慢。 json
你们可能对Java序列化都有一个错误的认识,认为Java序列化比JSON的序列化效率高而且序列化的数据小,其实实际上并不必定是这样,我此次就想经过实际测试来解开这个谜团。 数据结构
测试同一个Map<String,Object>并序列化为byte[],并再将byte[]反序列化为Map<String,Object>的过程。Object中包括String,Integer,Long,Boolean,Float,Double常规类型的数据。 ide
序列化:Map<String,Object> -> byte[] 性能
反序列化:byte[] -> Map<String,Object> 测试
测试各类大小不一样的Map,并循环执行同一操做N次,来获得一个相对稳定的线性结果。 this
手写Java(1.6.0_32)与Common Lang3(3.1)的SerializationUtils。 google
将采用Gson(2.2.2)与json-smart(2.0-RC2)两种不一样的JSON解析器。json-smart号称是速度最快的JSON解析器。 spa
序列化时间比较(y为序列化时间ms)
反序列化时间比较(y为反序列化时间ms)
序列化时间汇总比较(y为序列化与反序列化总时间ms)
序列化后byte大小比较(因为同类线重合显示为2条线)
序列化时间比较(y为序列化时间ms)
反序列化时间比较(y为反序列化时间ms)
序列化时间汇总比较(y为序列化与反序列化总时间ms)
序列化后byte大小比较(因为同类线重合显示为2条线)
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以固定的格式,稳定简单的数据结构大大简化了序列化过程,虽然也要建立新的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); }
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; } }
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); } }
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; } }
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; } }
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类型。