GO Protobuf实现消息序列化和反序列化的高效性

一、Protobuf简介

Protocol Buffers(简称Protobuf)是Google开源的一种轻便高效的序列化数据结构的方法,由Google基于一种二进制协议实现,通过源代码编译器生成源代码,具有良好的跨语言性。Protobuf可以生成Java、C++、Python等语言的源代码,且序列化后的数据大小非常的小, 这种方式比XML快许多倍,同时也比JSON快。

二、Protobuf的使用

Protobuf结构体定义包含name,tag和type三个成员,其中name表示结构体成员名称,tag表示用整形表示的序号,type表示结构体成员数据类型。

syntax = "proto3";
package example;
message Person {
    string name = 1;
    int32 age = 2;
    string address = 3;
}

在GO中使用Protobuf,首先需要安装Protobuf。

go get -u github.com/golang/protobuf/proto

使用Protobuf需要创建.proto文件并且定义好结构体,然后使用protoc编译器将.proto文件编译成目标语言的源代码文件。

//编译.proto文件
protoc --go_out=. person.proto

Protobuf提供了基本的Marshal和Unmarshal方法来进行序列化与反序列化操作。

package main

import (
    "github.com/golang/protobuf/proto"
    "example"
)

func main() {
    // 创建结构体实例
    p1 := &example.Person{
        Name:    "John",
        Age:     30,
        Address: "New York",
    }
    // 序列化
    data, err := proto.Marshal(p1)
    if err != nil {
        log.Fatal("marshaling error: ", err)
    }
    // 反序列化
    p2 := &example.Person{}
    err = proto.Unmarshal(data, p2)
    if err != nil {
        log.Fatal("unmarshaling error: ", err)
    }
    // p1 and p2 should contain the same data.
    fmt.Println("p1:", p1)
    fmt.Println("p2:", p2)
}

三、Protobuf的高效性

1、数据大小

与JSON数据格式相比,Protobuf序列化后的数据更小,可以将数据传输的时间和成本的最小化。

//结构体定义
message Example {
    string field_one = 1;
    int32 field_two = 2;
    bool field_three = 3;
}
//JSON格式的数据大小
{
    "field_one": "Hello World!",
    "field_two": 12345,
    "field_three": true
} 
//Protobuf格式的数据大小
data: 0a0c48656c6c6f20576f726c642109

2、效率

使用Protobuf进行序列化和反序列化操作的效率非常高。下面是一个比较序列化和反序列化操作的时间使用情况的代码片段

p1 := &example.Person{
        Name:    "John",
        Age:     30,
        Address: "New York",
}
// Marshal the data and record the time it takes to do so.
start := time.Now()
data, err := proto.Marshal(p1)
elapsed := time.Since(start)
fmt.Printf("protobuf marshaling time elapsed: %s\n", elapsed)

在大规模数据的情况下,使用Protobuf所节省的时间和资源是非常可观的。

四、总结

GO Protobuf实现消息序列化和反序列化的高效性使得它成为了一种高效且便于扩展性的数据交换方式。而且,由于Protobuf的良好跨语言特性,它可以轻松地在多种不同平台和语言之间交换数据。

完整代码示例

syntax = "proto3";
package example;
message Person {
    string name = 1;
    int32 age = 2;
    string address = 3;
}


package main

import (
    "fmt"
    "github.com/golang/protobuf/proto"
    "log"
    "time"
    "example"
)

func main() {
    // test protobuf encoding and decoding for example.Person
    p1 := &example.Person{
        Name:    "John",
        Age:     30,
        Address: "New York",
    }
    // Marshal the data.
    start := time.Now()
    data, err := proto.Marshal(p1)
    elapsed := time.Since(start)
    fmt.Printf("protobuf marshaling time elapsed: %s\n", elapsed)
    if err != nil {
        log.Fatal("marshaling error: ", err)
    }

    // Display the raw protobuf bytes.
    fmt.Printf("raw Protobuf bytes: %q\n", data)

    // Unmarshal the data back into a person struct.
    p2 := &example.Person{}
    start = time.Now()
    err = proto.Unmarshal(data, p2)
    elapsed = time.Since(start)
    fmt.Printf("protobuf unmarshaling time elapsed: %s\n", elapsed)
    if err != nil {
        log.Fatal("unmarshaling error: ", err)
    }

    // Display the original and unmarshaled structs.
    fmt.Println("Original struct  :", p1)
    fmt.Println("Unmarshaled struct:", p2)
}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/270761.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-16 13:38
下一篇 2024-12-16 13:38

相关推荐

  • 金额选择性序列化

    本文将从多个方面对金额选择性序列化进行详细阐述,包括其定义、使用场景、实现方法等。 一、定义 金额选择性序列化指根据传入的金额值,选择是否进行序列化,以达到减少数据传输的目的。在实…

    编程 2025-04-29
  • 运维Python和GO应用实践指南

    本文将从多个角度详细阐述运维Python和GO的实际应用,包括监控、管理、自动化、部署、持续集成等方面。 一、监控 运维中的监控是保证系统稳定性的重要手段。Python和GO都有强…

    编程 2025-04-29
  • go-chassis

    本文将深入探究go-chassis,包括它的基本概念,特性,以及如何使用它构建微服务应用程序。 一、微服务架构及其优势 微服务架构是一种将应用程序拆分为小型、自治服务的体系结构。每…

    编程 2025-04-29
  • RabbitMQ和Yii2的消息队列应用

    本文将探讨RabbitMQ和Yii2之间的消息队列应用。从概念、安装和配置、使用实例等多个方面详细讲解,帮助读者了解和掌握RabbitMQ和Yii2的消息队列应用。 一、Rabbi…

    编程 2025-04-29
  • 使用Go-Redis获取Redis集群内存使用率

    本文旨在介绍如何使用Go-Redis获取Redis集群的内存使用率。 一、Go-Redis简介 Go-Redis是一个用于连接Redis服务器的Golang客户端。它支持Redis…

    编程 2025-04-28
  • Kong 使用第三方的go插件

    本文将针对Kong使用第三方的go插件进行详细阐述。首先,我们解答下标题的问题:如何使用第三方的go插件?我们可以通过编写插件来达到此目的。 一、插件架构介绍 Kong的插件系统采…

    编程 2025-04-28
  • 理解Java反序列化(Java Deserialization Vulnerability)

    本文将从多个方面深入探讨Java反序列化漏洞,对于笔者所总结的经验和教训,以及掌握Java反序列化的设计模式、最佳实践和防范措施。 一、Java反序列化漏洞概述 Java反序列化漏…

    编程 2025-04-28
  • Go中struct的初始化

    本文将从多个方面详细阐述Go中struct的初始化方式,包括使用字面量初始化、使用new函数初始化以及使用构造函数等。通过本文的介绍,读者能够更深入的了解Go中struct的初始化…

    编程 2025-04-28
  • ROS线程发布消息异常解决方法

    针对ROS线程发布消息异常问题,我们可以从以下几个方面进行分析和解决。 一、检查ROS代码是否正确 首先,我们需要检查ROS代码是否正确。可能会出现的问题包括: 是否正确初始化RO…

    编程 2025-04-28
  • Trocket:打造高效可靠的远程控制工具

    如何使用trocket打造高效可靠的远程控制工具?本文将从以下几个方面进行详细的阐述。 一、安装和使用trocket trocket是一个基于Python实现的远程控制工具,使用时…

    编程 2025-04-28

发表回复

登录后才能评论