一、背景有項目需要傳輸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類型。 |