一、背景有项目需要传输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) 反序列化时间比较(y为反序列化时间ms) 序列化时间汇总比较(y为序列化与反序列化总时间ms) 序列化后byte大小比较(由于同类线重合显示为2条线) Map大小(100-1000)循环1万次序列化时间比较(y为序列化时间ms) 反序列化时间比较(y为反序列化时间ms) 序列化时间汇总比较(y为序列化与反序列化总时间ms) 序列化后byte大小比较(由于同类线重合显示为2条线) 比较总结Map在小于100时: Map在大于100小于1000时: 并不是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); } 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;
}
}
P.S. 我也测试过Map<string,string>固定数据类型value只为String的情况,这时Java与JSON的性能的差距会减小,但JSON序列化性能与数据大小还是占优势,尤其是反序列化的速度JSON更出色。 Gson在数值反序列化后,因为Object无法确定类型,Map中的Long,Integer,Float统一转为了Double类型。 |