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;
}
测试代码:
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可以节约不少内存空间的。