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預設的序列化都很差,