java原生序列化慢在哪裏?


Java原生序列化和二進制序列化性能比較

序列化速度

package com.clq.netty.serializable;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;

/**
 * Created by clq on 2018/7/20.
 */
public class UserInfo implements Serializable{

    private String name;
    private int id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public byte[] CodeC(ByteBuffer byteBuffer) {
        byteBuffer.clear();
       // ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byte[] bytes = this.getName().getBytes();
        byteBuffer.putInt(bytes.length);
        byteBuffer.put(bytes);
        byteBuffer.putInt(this.getId());
        byteBuffer.flip();
        bytes = null;
        byte [] bytes1 = new byte[byteBuffer.remaining()];
        byteBuffer.get(bytes1);
        return bytes1;
    }

    public static void main(String[] args) throws IOException {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1234);
        userInfo.setName("Welcome to Serializable");
        long begin = System.currentTimeMillis();
        for(int i=0; i<1000000; i++) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(userInfo);
            oos.flush();
            oos.close();
            byte[] bytes = bos.toByteArray();
            bos.close();
        }
        System.out.println("Java序列化耗時: "+(System.currentTimeMillis()-begin)+"ms");
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        Long start =System.currentTimeMillis();
        for(int i=0;i<1000000;i++) {
            byte[] bytes = userInfo.CodeC(byteBuffer);
        }
        System.out.println("二進制序列化:"+(System.currentTimeMillis()-start)+"ms");
        // System.out.println("JDK Serializable length:"+bytes.length);
       // System.out.println("NIO Serializable length:"+userInfo.CodeC().length);
    }
}

打印結果: Java序列化耗時: 1388ms 二進制序列化:118ms java原生序列化的速度是二進制序列化速度的 8.19%

序列化大小

public static void main(String[] args) throws IOException {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1234);
        userInfo.setName("Welcome to Serializable");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(userInfo);
        oos.flush();
        oos.close();
        byte[] bytes = bos.toByteArray();
        bos.close();
        System.out.println("JDK Serializable length:"+bytes.length);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        System.out.println("NIO Serializable length:"+userInfo.CodeC(buffer).length);
    }

JDK Serializable length:119 二進制 Serializable length:31 jdk序列化大小是二進制序列化大小的3.83倍

二進制字節碼

java序列化

aced 0005 7372 0023 636f 6d2e 636c 712e
6e65 7474 792e 7365 7269 616c 697a 6162
6c65 2e55 7365 7249 6e66 6fb5 d8bd 7f01
280b d402 0002 4900 0269 644c 0004 6e61
6d65 7400 124c 6a61 7661 2f6c 616e 672f
5374 7269 6e67 3b78 7000 0004 d274 0017
5765 6c63 6f6d 6520 746f 2053 6572 6961
6c69 7a61 626c 65

java序列化 二進制序列化

0000 0017 5765 6c63 6f6d 6520 746f 2053   
6572 6961 6c69 7a61 626c 6500 0004 efbf
bd

二進制序列化

原因分析

java的序列化後的碼流可以得出: Java本身並不支持跨語言,因爲加入了序列化版本號,類名等信息,所以導致碼流變大,速度變慢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章