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/zh-tw/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

發表回復

登錄後才能評論