serialization-protobuf

java : http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html

 

protobuf 简介:是一种序列化与结构化数据的一种机制,具有跨平台、解析速度快、序列化数据体积小、扩展性高、使用简单的特点

目标:验证protobuf序列化的内存占用量低于Java的直接序列化

 

java的实现:

 public static void serialize(Serializable obj, OutputStream outputStream) {
        if (outputStream == null) {
            throw new IllegalArgumentException("The OutputStream must not be null");
        }
        ObjectOutputStream out = null;
        try {
            // stream closed in the finally
            out = new ObjectOutputStream(outputStream);
            out.writeObject(obj);
            
        } catch (IOException ex) {
            throw new SerializationException(ex);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException ex) {
                // ignore close exception
            }
        }
    }

    public static byte[] serialize(Serializable obj) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
        serialize(obj, baos);
        return baos.toByteArray();
    }

 

protoBuf的实现:

需要先定义 User.proto 文件,然后通过protoc.exe 进行代码生成

D:\master\tts_search\serializer\src\proto>protoc.exe --java_out=. User.proto

 User.proto的定义如下:

option java_package = "com.ddd.fff.tts.search.serializer.proto";
option java_outer_classname = "UserProto";

message User {
    required string username = 1;
    optional string password = 2;
    repeated User friendList = 3;
}

 

扫描二维码关注公众号,回复: 488274 查看本文章

 

测试代码:

package test.ddd.serializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.SerializationUtils;

import com.google.common.io.Files;
import com.ddd.fff.tts.search.serializer.proto.UserProto;

public class TestSerialization2 {
	public static void main(String[] args) throws Exception {
		testJava();
		testProto();
	}  
	
	private static void testProto()  throws Exception {
		UserProto.User.Builder me = UserProto.User.newBuilder();
		me.setUsername("xinchun.wang");
		me.setPassword("123456");

		for(int i =0;i<100000;i++){
			UserProto.User.Builder she = UserProto.User.newBuilder();
			she.setPassword("pass"+i);
			she.setUsername("name"+i);
			me.addFriendList(she);
		}

		UserProto.User user = me.build();

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		user.writeTo(output);

		// -------------- 分割线:上面是发送方,将数据序列化后发送 ---------------

		byte[] byteArray = output.toByteArray();
		System.out.println(byteArray.length);

		ByteArrayInputStream input = new ByteArrayInputStream(byteArray);

		// 反序列化
		UserProto.User xxg2 = UserProto.User.parseFrom(input);
		System.out.println(xxg2);
	
	}
	
	private static void testJava() throws Exception {
		User me = new User();
		me.setPassword("123456");
		me.setUsername("xinchun.wang");

		for (int i = 0; i < 100000; i++) {
			User she = new User();
			she.setPassword("pass"+i);
			she.setUsername("name"+i);
			me.getFriendList().add(she);
		}

		System.out.println(SerializationUtils.serialize(me).length);
		Files.write(SerializationUtils.serialize(me), new File("data"));
	}
	
	
	public static class User implements Serializable{
		private static final long serialVersionUID = 1L;
		private String username;
		private String password;
		
		private List<User> friendList = new ArrayList<User>();
		
		public String getUsername() {
			return username;
		}
		public void setUsername(String username) {
			this.username = username;
		}
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		public List<User> getFriendList() {
			return friendList;
		}
		public void setFriendList(List<User> friendList) {
			this.friendList = friendList;
		}
	}
}

 

输出:

java:4678004,约4M

proto:2377802,约2M

 

可见在有缓存的地方,还是用protoBuf可以节约不少内存空间的。

 

 

 

猜你喜欢

转载自wangxinchun.iteye.com/blog/2368102
今日推荐