• 序列化与反序列化及不同序列化方式的性能对比


    在现代分布式系统中,序列化和反序列化是不可或缺的环节。它们用于将对象转换为可传输的字节流,并在接收端重建对象。本文将探讨几种常见的序列化方式,包括JSON、Java原生序列化和Protobuf,并通过实例代码进行性能对比。

    序列化方式简介
    1. JSON: 简单、可读性强,但性能和体积上相对较差。
    2. Java原生序列化: Java内置,使用简单,但体积较大且性能一般。
    3. Protobuf (Protocol Buffers): Google开发的高效序列化框架,性能和体积优于JSON和Java原生序列化。
    实例代码

    我们将使用一个简单的类 Cat 进行序列化和反序列化测试。Cat 类包含两个属性:nameage

    1. import java.io.*;
    2. class Cat implements Serializable {
    3. private String name;
    4. private int age;
    5. // Constructors, getters, and setters
    6. public Cat(String name, int age) {
    7. this.name = name;
    8. this.age = age;
    9. }
    10. // toString method
    11. @Override
    12. public String toString() {
    13. return "Cat{" +
    14. "name='" + name + '\'' +
    15. ", age=" + age +
    16. '}';
    17. }
    18. }
    JSON序列化和反序列化

    我们使用 Jackson 库进行JSON序列化和反序列化。

    1. import com.fasterxml.jackson.databind.ObjectMapper;
    2. public class JsonSerialization {
    3. private static ObjectMapper objectMapper = new ObjectMapper();
    4. public static String serialize(Cat cat) throws IOException {
    5. return objectMapper.writeValueAsString(cat);
    6. }
    7. public static Cat deserialize(String json) throws IOException {
    8. return objectMapper.readValue(json, Cat.class);
    9. }
    10. }

    Java原生序列化和反序列化

    1. public class NativeSerialization {
    2. public static byte[] serialize(Cat cat) throws IOException {
    3. try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
    4. ObjectOutputStream oos = new ObjectOutputStream(bos)) {
    5. oos.writeObject(cat);
    6. return bos.toByteArray();
    7. }
    8. }
    9. public static Cat deserialize(byte[] data) throws IOException, ClassNotFoundException {
    10. try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
    11. ObjectInputStream ois = new ObjectInputStream(bis)) {
    12. return (Cat) ois.readObject();
    13. }
    14. }
    15. }
    Protobuf序列化和反序列化

    首先,定义Protobuf的 .proto 文件:

    1. syntax = "proto3";
    2. message Cat {
    3. string name = 1;
    4. int32 age = 2;
    5. }

    生成Java类后:

    1. import com.google.protobuf.InvalidProtocolBufferException;
    2. import example.CatProto.Cat;
    3. public class ProtobufSerialization {
    4. public static byte[] serialize(Cat cat) {
    5. return cat.toByteArray();
    6. }
    7. public static Cat deserialize(byte[] data) throws InvalidProtocolBufferException {
    8. return Cat.parseFrom(data);
    9. }
    10. }
    性能对比

    我们通过以下代码进行性能测试:

    1. import java.io.IOException;
    2. import java.util.Arrays;
    3. public class SerializationPerformanceTest {
    4. public static void main(String[] args) throws IOException, ClassNotFoundException {
    5. Cat cat = new Cat("Whiskers", 3);
    6. // JSON
    7. long jsonStart = System.nanoTime();
    8. String json = JsonSerialization.serialize(cat);
    9. Cat jsonCat = JsonSerialization.deserialize(json);
    10. long jsonEnd = System.nanoTime();
    11. System.out.println("JSON time: " + (jsonEnd - jsonStart));
    12. // Native
    13. long nativeStart = System.nanoTime();
    14. byte[] nativeData = NativeSerialization.serialize(cat);
    15. Cat nativeCat = NativeSerialization.deserialize(nativeData);
    16. long nativeEnd = System.nanoTime();
    17. System.out.println("Native time: " + (nativeEnd - nativeStart));
    18. // Protobuf
    19. example.CatProto.Cat protoCat = example.CatProto.Cat.newBuilder().setName("Whiskers").setAge(3).build();
    20. long protoStart = System.nanoTime();
    21. byte[] protoData = ProtobufSerialization.serialize(protoCat);
    22. example.CatProto.Cat protoCatDeserialized = ProtobufSerialization.deserialize(protoData);
    23. long protoEnd = System.nanoTime();
    24. System.out.println("Protobuf time: " + (protoEnd - protoStart));
    25. }
    26. }
    结论

    根据测试结果,Protobuf的序列化和反序列化性能优于JSON和Java原生序列化。虽然JSON的可读性强,但在性能和体积上,Protobuf更具优势。因此,在对性能和体积有较高要求的场景下,推荐使用Protobuf进行序列化。

    通过以上实例代码和测试结果,我们可以更好地理解不同序列化方式的优缺点,并根据具体需求选择合适的序列化方式。

  • 相关阅读:
    [2023.09.22]:探索Rust编写基于web_sys的WebAssembly编辑器:挑战输入光标定位的实践
    [CM311-1A]-安卓设备视频分辨率 DPI 以及刷新率问题
    C++:多态
    N32学习笔记9-串口dma方式收发数据+printf的代码版本
    HTML西安旅游网页设计作业成品 大学生旅游风景区网页设计作业模板下载 静态HTML旅游景点网页制作下载 DW网页设计代码
    Java 八股文
    汉诺塔 --- 递归回溯算法练习一
    使用Python操作MSSQL数据库.
    每日刷题3——牛客,算术转换和二级指针
    11.30 WAVE SUMMIT+2022将在深圳举办,官网报名通道正式开启
  • 原文地址:https://blog.csdn.net/m0_68570169/article/details/140400993