1. 程式人生 > >自定義序列化和JDK序列化比較

自定義序列化和JDK序列化比較

實體類

自定義實體類,其中實現了自定義的兩種序列化方式,原理就是將物件轉為二進位制。

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[] value = this.userName.getBytes();//userName轉換為位元組陣列value
		buffer.putInt(value.length);//寫入位元組陣列value的長度
		buffer.put(value);//寫入位元組陣列value的值
		buffer.putInt(this.userID);//寫入userID的值
		buffer.flip();//準備讀取buffer中的資料
		value = null;
		byte[] result = new byte[buffer.remaining()];
		buffer.get(result);//buffer中的資料寫入位元組陣列並作為結果返回
		return result;
    }

	//自行序列化方法2
    public byte[] codeC(ByteBuffer buffer) {
		buffer.clear();
		byte[] value = this.userName.getBytes();
		buffer.putInt(value.length);
		buffer.put(value);
		buffer.putInt(this.userID);
		buffer.flip();
		value = null;
		byte[] result = new byte[buffer.remaining()];
		buffer.get(result);
		return result;
    }
}

測試序列化後位元組大小

/**
 * 類說明:測試序列化後位元組大小
 */
public class TestUserInfo {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
		UserInfo info = new UserInfo();
		info.buildUserID(100).buildUserName("Welcome to Netty");
		//使用jdk的序列化
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream os = new ObjectOutputStream(bos);
		os.writeObject(info);
		os.flush();
		os.close();
		byte[] b = bos.toByteArray();
		System.out.println("The jdk serializable length is : " + b.length);
		bos.close();
		//使用自行的序列化
		System.out.println("-------------------------------------");
		System.out.println("The byte array serializable length is : "
			+ info.codeC().length);
    }

}

結果:
在這裡插入圖片描述
可以看出,jdk序列化後的位元組長度明顯大於自定義的長度。

測試序列化效能差異

/**
 * 類說明:測試序列化效能差異
 */
public class PerformTestUserInfo {

    public static void main(String[] args) throws IOException {
        UserInfo info = new UserInfo();
        info.buildUserID(100).buildUserName("Welcome to Netty");
        int loop = 1000000;

        //使用jdk的序列化
        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(info);
            os.flush();
            os.close();
            byte[] b = bos.toByteArray();
            bos.close();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("The jdk serializable cost time is  : "
            + (endTime - startTime) + " ms");

        //使用自行的序列化
        System.out.println("-------------------------------------");
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        startTime = System.currentTimeMillis();
        for (int i = 0; i < loop; i++) {
            byte[] b = info.codeC(buffer);
        }
        endTime = System.currentTimeMillis();
        System.out.println("The byte array serializable cost time is : "
            + (endTime - startTime) + " ms");

        }

}

結果:
在這裡插入圖片描述
可以看出jdk的執行時間是自定義的18倍左右。

總結

jdk的序列化方式雖然很簡單,但是效率很低。