无情 @ Tue Jan 12 11:33:05 CST 2016 阅读(3777)
protobuf; 序列化;


我们在APP项目中API接口设计的时候,可能要考虑带宽、跨语言、版本的兼容等问题。比较常见的做法有两种:一是把对象包装成JSON字符串传输,二是采用java对象的序列化和反序列化。随着Google工具protoBuf的开源,protobuf也是个不错的选择。对JSON,Object Serialize,ProtoBuf 做个对比。

测试内容

 序列化时间

 

 bytes直接数大小

  

 相关测试代码

 

 User对象

import java.io.Serializable;
 public class User implements Serializable {
     /**
      * @Fields serialVersionUID : TODO
      */
     private static final long serialVersionUID = 1L;
     private String            name;
     private Integer           age;
     private String            phone;
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this.name = name;
     }
     public Integer getAge() {
         return age;
     }
     public void setAge(Integer age) {
         this.age = age;
     }
     public String getPhone() {
         return phone;
     }
     public void setPhone(String phone) {
         this.phone = phone;
     }

     

     

     

     UserVoProtos.proto代码

     

 package serialize;
     option java_package = "com.demo.compared";
     option java_outer_classname="UserVoProtos";
     message User{
     optional string name = 1;
     optional int32 age = 2;
     optional string phone = 3;
     }

     创建完成主动生成了UserVoProtos.java

     

     

     

     

      MAIN主类

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
/**
 * 
  * @ClassName: Main
  * @Description: 
  * @author zhuhuipei
  * @date 2016年1月12日 上午11:15:00
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Main.testGson();
        Main.testSerial();
        Main.testProtoBuf();
    }
    public static void testGson() {
        long t=System.currentTimeMillis();
        Gson gson = new Gson();
        String json = gson.toJson(getUser());
        System.out.println("Gson消耗的毫秒数:"+(System.currentTimeMillis()-t));
        System.out.println("Gson字节数:" + json.getBytes().length);
        System.out.println("=====================");
    }
    public static void testSerial() throws Exception {
        long t=System.currentTimeMillis();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream os = new ObjectOutputStream(bos);
        os.writeObject(getUser());
        os.flush();
        os.close();
        byte[] b = bos.toByteArray();
        System.out.println("java序列化消耗的毫秒数:"+(System.currentTimeMillis()-t));
        System.out.println("java序列化后的字节数:" + b.length);
        bos.close();
        System.out.println("=====================");
    }
    public static void testProtoBuf() throws Exception {
        long t=System.currentTimeMillis();
        UserVoProtos.User.Builder builder = UserVoProtos.User.newBuilder();
        builder.setAge(10);
        builder.setName("我是1237777777777");
        builder.setPhone("13888888888");
        UserVoProtos.User vo = builder.build();
        byte[] v = vo.toByteArray();
        System.out.println("rotobuf消耗的毫秒数:"+(System.currentTimeMillis()-t));
        System.out.println("Protobuf字节数:" + v.length);
        System.out.println("=====================");
      
    }
    public static User getUser() {
        User user = new User();
        user.setAge(10);
        user.setName("我是1237777777777");
        user.setPhone("13888888888");
        return user;
    }

   

   

   

   

   结果如图:

    


上面的例子可以看出值字节压缩方面protobuf远远优于其他2个,而java原生的序列化是最差的,所以实际项目开发中很少使用java原生态的。


方式
优点缺点
 JSON   跨语言、格式清晰一目了然字节数比较大,需要第三方类库
java Serializejava原生方法不依赖外部类库字节数比较大,不能跨语言
Google protobuf跨语言、字节数比较少编写.proto配置用protoc工具生成对应的代码