1、编解码名词含义:将java对象编码为字节数组或者bytebuffer对象,当远程服务读取到byterbuffer对象或者字节数组是,需要将其编解码为发送是的java对象。
2、我用过的序列化方式以下三种:1)对象实现Serializable接口 2)使用google的json或者阿里巴巴的FastJSon 3)使用google的protobuf 4)Facebook的Thrift 主要用于静态数据交换,已知的数据结构,负责搭建大型数据交换接存储的工具 5)Jboss的Marshalling 是一个java对象的序列化api包
本次主要查看第一种serializable 序列化后的编码性能,码流大小,api工具是否方便
1)pojo类
public class UserInfo implements Serializable {
private static final long serialVersionUid=1L;
private String userName;
private int userID;
public UserInfo buildUserName(String username) {
this.userName = username;
return this;
}
public UserInfo buildUserID(int userID) {
this.userID = userID;
return this;
}
public final String getUserName() {
return userName;
}
public final void setUserName(String userName) {
this.userName = userName;
}
public final int getUserID() {
return userID;
}
public final void setUserID(int userID) {
this.userID = userID;
}
public byte[] codeC(){
ByteBuffer buffer = ByteBuffer.allocate(1024);
byte[] bytes = this.userName.getBytes();
buffer.putInt(bytes.length);
buffer.put(bytes);
buffer.putInt(this.userID);
buffer.flip();
bytes=null;
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
usrinfo对象是一个普通pojo类,它实现了serializable接口,,通过jdk默认的序列化机制进行序列化和反序列化。
codec方法使用的是bytebuffer通用的二进制编码技术对userinfo对象进行编码,编码结果仍然是byte数组,
2)测试类
public class TestUserInfo {
public static void main(String[] args) throws IOException {
UserInfo userInfo = new UserInfo();
userInfo.buildUserID(100).buildUserName("welcome to netty");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(userInfo);
os.flush();
os.close();
byte[] bytes = bos.toByteArray();
System.out.println("the jdk serializable length is:"+bytes.length);
bos.close();
System.out.println("=====================================");
System.out.println("the byte array serializable length:"+userInfo.codeC().length);
}
}
3)运行结果

从上可以看出,二进制明细优于jdk序列化。因为编解码后的字节数组越大,存储的时候约占空间,硬件成本就越高,网络传送就越高,
4)编码100万次,新增一个重载方法
/**
* 修改后的
* @return
*/
public byte[] codeC(ByteBuffer buffer){
buffer.clear();
byte[] bytes = this.userName.getBytes();
buffer.putInt(bytes.length);
buffer.put(bytes);
buffer.putInt(this.userID);
buffer.flip();
bytes=null;
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
public class PerformTestUserInfo {
public static void main(String[] args) throws IOException {
UserInfo userInfo = new UserInfo();
userInfo.buildUserID(100).buildUserName("weclome to netty");
int loop=1000000;
ByteArrayOutputStream bos=null;
ObjectOutputStream os=null;
long startTime = System.currentTimeMillis();
for(int i=0;i<loop;i++){
bos=new ByteArrayOutputStream();
os=new ObjectOutputStream(bos);
os.writeObject(userInfo);
os.flush();
os.close();
byte[] bytes = bos.toByteArray();
bos.close();
}
long endTime = System.currentTimeMillis();
System.out.println("the jdk serializable cost time is:"+(endTime-startTime)+"ms");
System.out.println("=====================================");
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
startTime = System.currentTimeMillis();
for(int i=0;i<loop;i++){
byte[] bytes = userInfo.codeC(byteBuffer);
}
endTime = System.currentTimeMillis();
System.out.println("the byte array serializable cost time is:"+(endTime-startTime)+"ms");
}
}
,统计下测试时间:
以上结果证明:无论序列化后的码流大小还是序列化的性能,jdk默认的序列化都很差,