您的位置:首页 > Web前端 > JavaScript

比较protoStuff和fastjson以及实现Serializable接口序列化的效率问题

2017-08-03 18:41 597 查看
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。这是百度百科对于序列化和反序列化的解释。本人在平时的工作中主要使用实现Serializable接口和fastjson来进行序列化,无意间发现了在googel的protoBuf基础上上改进的序列化开源框架protoStuff,传说这个框架的效率非常高,之后自己就写了点代码测试了一下,发现效率确实不错。

protoBuf的maven依赖如下:

<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.4.0</version>
</dependency>


测试类Test.java:

package ProtostuffTest1.ProtostuffTest1;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class Test {

public static void main(String[] args) throws IOException, ClassNotFoundException {

Student student = new Student();
student.setName("luocheng");
student.setAge(24);
student.setStudentNo("2017080222");
student.setSchoolName("yangzi");

Student1 student1 = new Student1();

student1.setName("luocheng");
student1.setAge(24);
student1.setStudentNo("2017080222");
student1.setSchoolName("yangzi");

Student2 student2 = new Student2();

student2.setName("luocheng");
student2.setAge(24);
student2.setStudentNo("2017080222");
student2.setSchoolName("yangzi");

Student3 student3 = new Student3();

student3.setName("luocheng");
student3.setAge(24);
student3.setStudentNo("2017080222");
student3.setSchoolName("yangzi");

//使用开源的Protostuff序列化和反序列化
byte[] serializerResult = Util.serializer(student);

System.out.println("使用开源的Protostuff序列化和反序列化 size:" + serializerResult.length);

Student deSerializerResult = Util.deserializer(serializerResult,Student.class);
System.out.println("使用开源的Protostuff序列化Result:" + Arrays.toString(serializerResult));
System.out.println("使用开源的Protostuff反序列化Result:" + deSerializerResult.toString());

System.out.println("----------------------------------------------------");
//实现Serializable接口序列化和反序列化
int size = Util.calcSize(student1);
System.out.println("实现Serializable接口序列化和反序列化 size:" + size);

System.out.println("实现Serializable接口序列化和反序列化Result:" + student1.toString());
System.out.println("----------------------------------------------------");
//fastjson序列化
String studentJson = JSON.toJSONString(student3);
int size2 = studentJson.length();
//反序列化
JSONObject ins1 = JSON.parseObject(studentJson, JSONObject.class);
System.out.println("fastjson序列化 size:"+size2);
System.out.println("fastjson序列化Result:" + student2);
System.out.println("fastjson反序列化Result:" + ins1.toJSONString());

//序列化到本地
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:/Student2.txt"));
out.writeObject(student2);
out.close();

//反序列化
ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:/Student2.txt"));
Student2 student4=(Student2)in.readObject();
in.close();
int size3 = Util.calcSize(student2);
System.out.println("实现Serializable接口序列化和反序列化 size:" + size3);

System.out.println("实现Serializable接口序列化和反序列化Result:" + student4.toString());
System.out.println("----------------------------------------------------");
}

}


until.java类

package ProtostuffTest1.ProtostuffTest1;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Arrays;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

public class Util {
public Util(){};

public static <T> byte[] serializer(T o) {
Schema schema = RuntimeSchema.getSchema(o.getClass());
return ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(256));
}

public static <T> T deserializer(byte[] bytes, Class<T> clazz) {

T obj = null;
try {
obj = clazz.newInstance();
Schema schema = RuntimeSchema.getSchema(obj.getClass());
ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

return obj;
}
public static int calcSize(java.io.Serializable o) {
int ret = 0;
class DumbOutputStream extends OutputStream {
int count = 0;

public void write(int b) throws IOException {
count++; // 只计数,不产生字节转移
}

}
DumbOutputStream buf = new DumbOutputStream();
ObjectOutputStream os = null;
try {
os = new ObjectOutputStream(buf);
os.writeObject(o);
ret = buf.count;
} catch (IOException e) {
// No need handle this exception
e.printStackTrace();
ret = -1;
} finally {
try {
os.close();
} catch (Exception e) {
}
}

return ret;

}
}


使用protoStuff序列化类student.java

package ProtostuffTest1.ProtostuffTest1;

import io.protostuff.Tag;

public class Student {
@Tag(1)
private String name;
@Tag(2)
private String studentNo;
@Tag(3)
private int age;
@Tag(4)
private String schoolName;

// 关于@Tag,要么所有属性都有@Tag注解,要么都没有,不能一个类中只有部分属性有@Tag注解

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getStudentNo() {
return studentNo;
}

public void setStudentNo(String studentNo) {
this.studentNo = studentNo;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getSchoolName() {
return schoolName;
}

public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", studentNo='" + studentNo + '\'' +
", age=" + age +
", schoolName='" + schoolName + '\'' +
'}';
}
}


这是使用protoStuff序列化和反序列化之后的结构

使用开源的Protostuff序列化和反序列化 size:32
使用开源的Protostuff序列化Result:[10, 8, 108, 117, 111, 99, 104, 101, 110, 103, 18, 10, 50, 48, 49, 55, 48, 56, 48, 50, 50, 50, 24, 24, 34, 6, 121, 97, 110, 103, 122, 105]
使用开源的Protostuff反序列化Result:Student{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}


实现Serializable接口序列化的类Student1.java

package ProtostuffTest1.ProtostuffTest1;

import java.io.Serializable;

public class Student1 implements Serializable{

private static final long serialVersionUID = -36435658415657806L;

private String name;

private String studentNo;

private int age;

private String schoolName;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getStudentNo() {
return studentNo;
}

public void setStudentNo(String studentNo) {
this.studentNo = studentNo;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getSchoolName() {
return schoolName;
}

public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}

@Override
public String toString() {
return "Student1{" +
"name='" + name + '\'' +
", studentNo='" + studentNo + '\'' +
", age=" + age +
", schoolName='" + schoolName + '\'' +
'}';
a684

}
}


实现Serializable接口序列化的结果:

----------------------------------------------------
实现Serializable接口序列化和反序列化 size:167
实现Serializable接口序列化和反序列化Result:Student1{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}


fastjson就不多讲了,下面是综合对比结果:

使用开源的Protostuff序列化和反序列化 size:32
使用开源的Protostuff序列化Result:[10, 8, 108, 117, 111, 99, 104, 101, 110, 103, 18, 10, 50, 48, 49, 55, 48, 56, 48, 50, 50, 50, 24, 24, 34, 6, 121, 97, 110, 103, 122, 105]
使用开源的Protostuff反序列化Result:Student{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}
---------------------------------------------------- 实现Serializable接口序列化和反序列化 size:167 实现Serializable接口序列化和反序列化Result:Student1{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}
----------------------------------------------------
fastjson序列化 size:75
fastjson序列化Result:Student1{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}
fastjson反序列化Result:{"name":"luocheng","studentNo":"2017080222","schoolName":"yangzi","age":24}
实现Serializable接口序列化和反序列化 size:167
实现Serializable接口序列化和反序列化Result:Student1{name='luocheng', studentNo='2017080222', age=24, schoolName='yangzi'}
----------------------------------------------------


这是源码,有兴趣的同学自取:https://github.com/lwk123/ProtostuffTest

谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java
相关文章推荐