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

来源:互联网 发布:白头发食疗 知乎 编辑:程序博客网 时间:2024/06/06 03:53

序列化 (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 + '\'' +                  '}';      }}

实现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:75fastjson序列化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
谢谢!

阅读全文
0 0
原创粉丝点击