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可以节约不少内存空间的。