日期:2014-05-16  浏览次数:20456 次

几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比

最近研究了下google protobuf协议,顺便对比了一下json,xml,java序列化相关的数据对比,从几个纬度进行对比。

?

别人的相关测试数据:?http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

?

测试纬度

  • 序列化时间
  • 反序列化时间
  • bytes大小

测试代码

准备protobuf文件

?

import "InnerMessage.proto";
package demo; 
option java_package = "com.agapple.protobuf.data";
option java_outer_classname = "MessageProtos";
option optimize_for = SPEED ;  //CODE_SIZE,LITE_RUNTIME
option java_generic_services = false;
message Message {
	
	required string strObj = 1 [default="hello"];
	optional int32 int32Obj = 2;
	optional int64 int64Obj = 3;
	optional uint32 uint32Obj = 4;
	optional uint64 uint64Obj = 5;
	optional sint32 sint32Obj = 6;
	optional sint64 sint64Obj = 7;
	optional fixed32 fixed32Obj = 8;
	optional fixed64 fixed64Obj = 9;
	optional sfixed32 sfixed32Obj = 10;
	optional sfixed64 sfixed64Obj = 11;
	optional bool 	boolObj = 12;
	optional bytes 	bytesObj = 13;
	optional float folatObj = 14 [deprecated=true];
	repeated double doubleObj = 15 [packed=true]; //
	optional InnerMessage innerMessage = 16;
}

?

?

import "EnumType.proto";

package demo; 
option java_package = "com.agapple.protobuf.data";
option java_outer_classname = "InnerMessageProtos";

message InnerMessage { 
	optional string name = 1 [default = "name"];
	optional int32 id = 2;
	optional EnumType type = 3 [default = UNIVERSAL];
}

?

?

package demo; 
option java_package = "com.agapple.protobuf.data";
option java_outer_classname = "EnumTypeProtos";

enum EnumType {
	UNIVERSAL = 0; 
	WEB = 1; 
	IMAGES = 2; 
	LOCAL = 3; 
	NEWS = 4; 
	PRODUCTS = 5; 
	VIDEO = 6; 
}

?

?

基本上把protobuf支持的类型都囊括了,包括嵌套类型,枚举类型,以及各种int,uint,bool,bytes。 ?

?

依赖关系是Message.proto依赖了InnerMessage对象,而InnerMessage对象里包含了一个自定义枚举类型EnumType。

?

关于类型的使用可参见:?
?? ? ?http://code.google.com/intl/zh/apis/protocolbuffers/docs/reference/java-generated.html
?? ? ?http://code.google.com/intl/zh/apis/protocolbuffers/docs/proto.html

?

?

?

生成protobuf javabean

?

?

cd /home/ljh/work/code/src/main/java

/home/ljh/work/protobuf/bin/protoc --proto_path=com/agapple/protobuf/ --java_out=. com/agapple/protobuf/EnumType.proto
/home/ljh/work/protobuf/bin/protoc --proto_path=com/agapple/protobuf/ --java_out=. com/agapple/protobuf/InnerMessage.proto
/home/ljh/work/protobuf/bin/protoc --proto_path=com/agapple/protobuf/ --java_out=. com/agapple/protobuf/Message.proto

?

?通过protobuf自带的protoc进行编译,指定了protobuf文件的路径, 具体的文档:?http://code.google.com/intl/zh/apis/protocolbuffers/docs/proto.html#generating

?

?

运行脚本后就会生成对应的3个javabean文件: MessageProtos , InnerMessageProtos , EnumTypeProtos。

?

最后构造测试的protobuf bean代码

?

private static MessageProtos.Message getProtobufBean() {
        com.agapple.protobuf.data.MessageProtos.Message.Builder messageBuilder = MessageProtos.Message.newBuilder();

        messageBuilder.setStrObj("message");
        messageBuilder.setFolatObj(1f);
        messageBuilder.addDoubleObj(1d);
        messageBuilder.addDoubleObj(2d);
        messageBuilder.setBoolObj(true);

        messageBuilder.setBytesObj(ByteString.copyFrom(new byte[] { 1, 2, 3 }));
        messageBuilder.setInt32Obj(32);
        messageBuilder.setInt64Obj(64l);
        messageBuilder.setSint32Obj(232);
        messageBuilder.setSint64Obj(264);
        messageBuilder.setFixed32Obj(532);
        messageBuilder.setFixed64Obj(564);
        messageBuilder.setSfixed32Obj(2532);
        messageBuilder.setSfixed64Obj(2564);
        messageBuilder.setUint32Obj(632);