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

hex模式查看

二进制序列化

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

hex模式查看

原因分析

java的序列化后的码流可以得出: Java本身并不支持跨语言,因为加入了序列化版本号,类名等信息,所以导致码流变大,速度变慢。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券