序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
一些开源的序列化框架可提高对象序列化以及反序列化的性能,下面先介绍在java中怎样使用序列化框架,然后对序列化框架之间的性能进行对比。
所需jar包:
asm-5.0.3.jar
hessian-3.0.1.jar
kryo-3.0.2.jar
minlog-1.3.0.jar
mongo-java-driver-2.10.1.jar
objenesis-2.1.jar
protostuff-api-1.0.8.jar
protostuff-collectionschema-1.0.8.jar
protostuff-core-1.0.8.jar
protostuff-runtime-1.0.8.jar
reflectasm-1.10.1.jar
代码:
package com.zhanghao.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Registration;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
public class SerializationTest {
public static void main(String[] args) {
testKryo();
testHessian();
testJava();
}
//Kryo
private static void testKryo() {
Kryo kryo = new Kryo();
List<String> list = getList();
// 循环引用,默认关闭
kryo.setReferences(true);
// 注册类,默认没有注册
// Registration registration = kryo.register(List.class);
//序列化时间
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
Output output = new Output(1, 102400);
kryo.writeObject(output, list);
byte[] buf = output.toBytes();
output.flush();
}
System.out.println("序列化时间:" + (System.currentTimeMillis()-time) + "ms");
//序列化后字节数组大小
Output oOutput = new Output(1, 102400);
kryo.writeObject(oOutput, list);
byte[] buff = oOutput.toBytes();
oOutput.flush();
System.out.println("序列化后字节数组大小:" + buff.length);
//反序列化时间
time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
Input input = new Input(buff);
List<String> listStr = kryo.readObject(input, ArrayList.class);
input.close();
}
System.out.println("反序列化时间:" + (System.currentTimeMillis()-time) + "ms");
//序列化并反序列化时间
time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
Output output = new Output(1, 102400);
kryo.writeObject(output, list);
byte[] buf = output.toBytes();
output.flush();
Input input = new Input(buf);
List<String> strList = kryo.readObject(input, ArrayList.class);
input.close();
}
System.out.println("序列化并反序列化时间:" + (System.currentTimeMillis()-time) + "ms");
}
//Hessian
private static void testHessian() {
List<String> list = getList();
//序列化时间
try {
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
HessianOutput ho = new HessianOutput(os);
ho.writeObject(list);
byte[] buffer = os.toByteArray();
}
System.out.println("序列化时间:" + (System.currentTimeMillis()-time) +"ms");
} catch (Exception e) {
e.printStackTrace();
}
//序列化后字节数组大小及反序列化时间
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
HessianOutput ho = new HessianOutput(os);
ho.writeObject(list);
byte[] buffer = os.toByteArray();
System.out.println("序列化后字节数组大小:" + buffer.length);
long time = System.currentTimeMillis();
for(int i=0; i<100; i++) {
ByteArrayInputStream is = new ByteArrayInputStream(buffer);
HessianInput hi = new HessianInput(is);
List<String> strList = (List<String>) hi.readObject();
}
System.out.println("反序列化时间:" + (System.currentTimeMillis()-time) +"ms");
} catch (Exception e) {
e.printStackTrace();
}
//序列化并反序列化时间
try {
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
HessianOutput ho = new HessianOutput(os);
ho.writeObject(list);
byte[] buffer = os.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(buffer);
HessianInput hi = new HessianInput(is);
List<String> strList = (List<String>) hi.readObject();
}
System.out.println("序列化并反序列化时间:" + (System.currentTimeMillis()-time) +"ms");
} catch (Exception e) {
e.printStackTrace();
}
}
//Protostuff
private static void testProtostuff() {
ArrayList<String> list = getList();
Schema<ArrayList> schema = RuntimeSchema.getSchema(ArrayList.class);
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
byte[] protostuff = null;
try {
protostuff = ProtostuffIOUtil.toByteArray(list, schema, buffer);
System.out.println(protostuff.length);
} catch (Exception ex) {
ex.printStackTrace();
}
/* Schema<ArrayList> schema1 = RuntimeSchema.getSchema(ArrayList.class);
ArrayList<String> strList = new ArrayList<String>();
ProtostuffIOUtil.mergeFrom(protostuff,strList,schema1);
System.out.println(strList.get(0));*/
}
//Java
private static void testJava() {
List<String> list = getList();
//序列化时间
try {
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( new File("D:\\list.txt")));
oos.writeObject(list);
oos.flush();
}
System.out.println("序列化时间:" + (System.currentTimeMillis()-time) + "ms");
} catch (Exception e) {
e.printStackTrace();
}
//序列化字节数组大小
try {
File file = new File("D:\\list.txt");
FileInputStream fis = new FileInputStream(file);
System.out.println("序列化后字节数组大小:" + fis.available());
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
//反序列化时间
try {
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream( new File("D:\\list.txt")));
List<String> strList = (List<String>) ois.readObject();
ois.close();
}
System.out.println("反序列化时间:" + (System.currentTimeMillis()-time) + "ms");
} catch (Exception e) {
e.printStackTrace();
}
//序列化并反序列化时间
try {
long time = System.currentTimeMillis();
for (int i=0; i<100; i++) {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( new File("D:\\list.txt")));
oos.writeObject(list);
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream( new File("D:\\list.txt")));
List<String> strList = (List<String>) ois.readObject();
ois.close();
}
System.out.println("序列化并反序列化时间:" + (System.currentTimeMillis()-time) + "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
//初始化测试对象
private static ArrayList<String> getList() {
ArrayList<String> list = new ArrayList<String>();
for (int i=0; i<10000; i++) {
list.add(String.valueOf(i));
}
return list;
}
}
性能对比: