Google Protocol Buffer 傳輸資料相對其他格式較短的原理
原文連結: http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/, 作者:劉明
Google Protocol Buffer 的 Encoding
Protobuf 序列化後所生成的二進位制訊息非常緊湊,這得益於 Protobuf 採用的非常巧妙的 Encoding 方法。
考察訊息結構之前,讓我首先要介紹一個叫做 Varint 的術語。
Varint 是一種緊湊的表示數字的方法。它用一個或多個位元組來表示一個數字,值越小的數字使用越少的位元組數。這能減少用來表示數字的位元組數。
比如對於 int32 型別的數字,一般需要 4 個 byte 來表示。但是採用 Varint,對於很小的 int32 型別的數字,則可以用 1 個 byte 來表示。當然凡事都有好的也有不好的一面,採用 Varint 表示法,大的數字則需要 5 個 byte 來表示。從統計的角度來說,一般不會所有的訊息中的數字都是大數,因此大多數情況下,採用 Varint 後,可以用更少的位元組數來表示數字資訊。下面就詳細介紹一下 Varint。
Varint 中的每個 byte 的最高位 bit 有特殊的含義,如果該位為 1,表示後續的 byte 也是該數字的一部分,如果該位為 0,則結束。其他的 7 個 bit 都用來表示數字。因此小於 128 的數字都可以用一個 byte 表示。大於 128 的數字,比如 300,會用兩個位元組來表示:1010 1100 0000 0010
下圖演示了 Google Protocol Buffer 如何解析兩個 bytes。注意到最終計算前將兩個 byte 的位置相互交換過一次,這是因為 Google Protocol Buffer 位元組序採用 little-endian 的方式。
圖 6. Varint 編碼
訊息經過序列化後會成為一個二進位制資料流,該流中的資料為一系列的 Key-Value 對。如下圖所示:
圖 7. Message Buffer
採用這種 Key-Pair 結構無需使用分隔符來分割不同的 Field。對於可選的 Field,如果訊息中不存在該 field,那麼在最終的 Message Buffer 中就沒有該 field,這些特性都有助於節約訊息本身的大小。
以程式碼清單 1 中的訊息為例。假設我們生成如下的一個訊息 Test1:
Test1.id = 10; Test1.str = “hello”;
則最終的 Message Buffer 中有兩個 Key-Value 對,一個對應訊息中的 id;另一個對應 str。
Key 用來標識具體的 field,在解包的時候,Protocol Buffer 根據 Key 就可以知道相應的 Value 應該對應於訊息中的哪一個 field。
Key 的定義如下:
(field_number << 3) | wire_type
可以看到 Key 由兩部分組成。第一部分是 field_number,比如訊息 lm.helloworld 中 field id 的 field_number 為 1。第二部分為 wire_type。表示 Value 的傳輸型別。
Wire Type 可能的型別如下表所示:
表 1. Wire Type
Type | Meaning | Used For |
---|---|---|
0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
1 | 64-bit | fixed64, sfixed64, double |
2 | Length-delimi | string, bytes, embedded messages, packed repeated fields |
3 | Start group | Groups (deprecated) |
4 | End group | Groups (deprecated) |
5 | 32-bit | fixed32, sfixed32, float |
在我們的例子當中,field id 所採用的資料型別為 int32,因此對應的 wire type 為 0。細心的讀者或許會看到在 Type 0 所能表示的資料型別中有 int32 和 sint32 這兩個非常類似的資料型別。Google Protocol Buffer 區別它們的主要意圖也是為了減少 encoding 後的位元組數。
在計算機內,一個負數一般會被表示為一個很大的整數,因為計算機定義負數的符號位為數字的最高位。如果採用 Varint 表示一個負數,那麼一定需要 5 個 byte。為此 Google Protocol Buffer 定義了 sint32 這種型別,採用 zigzag 編碼。
Zigzag 編碼用無符號數來表示有符號數字,正數和負數交錯,這就是 zigzag 這個詞的含義了。
如圖所示:
圖 8. ZigZag 編碼
使用 zigzag 編碼,絕對值小的數字,無論正負都可以採用較少的 byte 來表示,充分利用了 Varint 這種技術。
其他的資料型別,比如字串等則採用類似資料庫中的 varchar 的表示方法,即用一個 varint 表示長度,然後將其餘部分緊跟在這個長度部分之後即可。
通過以上對 protobuf Encoding 方法的介紹,想必您也已經發現 protobuf 訊息的內容小,適於網路傳輸。假如您對那些有關技術細節的描述缺乏耐心和興趣,那麼下面這個簡單而直觀的比較應該能給您更加深刻的印象。
對於程式碼清單 1 中的訊息,用 Protobuf 序列化後的位元組序列為:
08 65 12 06 48 65 6C 6C 6F 77
而如果用 XML,則類似這樣:
31 30 31 3C 2F 69 64 3E 3C 6E 61 6D 65 3E 68 65 6C 6C 6F 3C 2F 6E 61 6D 65 3E 3C 2F 68 65 6C 6C 6F 77 6F 72 6C 64 3E 一共 55 個位元組,這些奇怪的數字需要稍微解釋一下,其含義用 ASCII 表示如下: <helloworld> <id>101</id> <name>hello</name> </helloworld>
相關推薦
Google Protocol Buffer 傳輸資料相對其他格式較短的原理
原文連結: http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/, 作者:劉明 Google Protocol Buffer 的 Encoding Protobuf 序列化後所生成的二進位制訊息非常緊湊,這得益於
Netty使用Google Protocol Buffer完成伺服器高效能資料傳輸
一、什麼是Google Protocol Buffer(protobuf官方網站) 下面是官網給的解釋: Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structu
Google Protocol Buffer入門
解釋 -- rate plugin gcc 入門 新增 查找 abs 簡介 Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言數據標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,183 個
Google Protocol Buffer
長度 .com ID 成員 得到 規模 c 語言 ostream HR 簡介 什麽是 Google Protocol Buffer? 假如您在網上搜索,應該會得到類似這樣的文字介紹: Google Protocol Buffer( 簡稱 Protobuf) 是 Google
windows下Google Protocol Buffer 編譯安裝使用教程
轉載修改自:http://kuaile.in/archives/1214 protobuf的全稱是Protocol Buffer,它是google 的一種資料交換的格式,可用於用於分散式應用之間的資料通訊或者異構環境下的資料交換, 最近因為專案的需求,需要接觸Protobuf,在官方提供的壓縮包
Google Protocol Buffer 的使用和原理
簡介 Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言資料標準。Protobuf是一種輕便高效的結構化資料儲存格式,可以用於結構化資料序列化,或者說序列化。它很適合做資料儲存或 RPC 資料交換格式。可用於通
C++ Class Mapped Google Protocol Buffer Message
摘要 Google Protocol Buffer 是一個優秀的基於二進位制的網路訊息編解碼框架。應用於專案時,可以節省不少的人力資源、開發時間和程式BUG。但其不足之處是protobuf編譯器生成的C++訊息類(或者Java等其他語言的訊息類)冗餘資料過多,需要依賴於pro
Android 使用Google Protocol buffer協議
什麼是 Protocol buffer 它是用於對結構化資料進行序列化的一種靈活、高效、自動化的機制——類似XML,但是更小、更快、更簡單。您可以定義資料的結構化方式,然後使用特殊生成的原始碼輕鬆地在各種資料流和使用的各種語言之間讀寫結構化資料。 對於使用 J
從環境搭建開始學習使用Google Protocol Buffer和gRPC
首先安裝 golang/protobuf Golang 語言版本的 API 時,需要先安裝標準 C++ 實現的 protocol buffer google/protobuf,使用linux的話就是先到github上下載對應的二進位制檔案 下載完解壓之後將bin目錄加
Google Protocol Buffer 的使用(一)
一、什麼是Google Protocol Buffer下面是官網給的解釋:Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data. – thin
Google Protocol Buffer 的使用(二) Google Protocol Buffer 的使用(一)
一、protobuf應用場景 protobuf 在Java中的應用場景可以是序列化和反序列化,流可以通過檔案或者通過網路TCP/UDP等方式傳輸。新建一個.proto檔案 syntax = "proto3"; option java_package = "com.test.proto"; optio
Google Protocol Buffer 簡單介紹
以下內容主要整理自官方文件。 為什麼使用 Protocol Buffers 通常序列化和解析結構化資料的幾種方式? 使用Java預設的序列化機制。這種方式缺點很明顯:效能差、跨語言性差。 將資料編碼成自己定義的字串格式。簡單高效,但是僅適合比較簡單的資料格式。 使用XML序列化。比較普遍的做
Google Protocol Buffer序列化入門實戰(附原始碼)
Google Protocol Buffer入門實戰(附原始碼) Google Protocol Buffer(後面簡稱PB)是Google開源的一款二進位制序列化工具,佔用空間小,傳輸效率高。最近由於專案中使用到了PB,所以特地學習了PB,這篇文章也是自己學
eclipse4.4的google protocol buffer的proto檔案編輯器Protocol Buffer Editor安裝
eclipse4.4的proto檔案編輯器Protocol Buffer Editor安裝 google protocol buffer 檔案編輯器。 外掛專案名稱為protobuf-dt,是託管在google code上,國內現在已經連線不上google code了,在e
【神經網路與深度學習】Google Protocol Buffer介紹
簡介 什麼是 Google Protocol Buffer? 假如您在網上搜索,應該會得到類似這樣的文字介紹: Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言資料標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,1
【小松教你手遊開發】【unity實用技能】Google Protocol Buffer(protobuf) 使用和研究
由於專案使用的是c#,所以下面的範例也是用於c# 一、安裝Google Protocol Buffer 二、編寫一個bat檔案處理檔案,批量生成c#檔案,如: @echo off SETLOCAL ENABLEDELAYEDEXPANSION rem 查詢檔案
Google protocol buffer 的反射機制和應用
何謂反射? 我在工作中大量使用了 google protocal buffer, 為了方便描述, 下文簡稱為 pb. pb 的作用和基本使用方法在這裡就不再陳述, 相關的文章網上很多. 這裡主要介紹 pb 的反射機制. 什麼是反射機制呢? 該機制能在執行時, 對於任
關於google protocol buffer(PB)的優缺點和一些個人的理解
-------------------------------- 網路名稱:name 網路型別:type 卷積層引數:convolution_param -------------------------------- 如果使用protobuf實現,首先要寫一個proto檔案(不妨叫VGG.
Google protocol buffer檔案的原理和使用
在此學習.protoc檔案,在網上有一篇博文寫的很好,轉了下: 一.什麼是protobuf protobuf全稱Google Protocol Buffers,是google開發的的一套用於資料儲存,網路通訊時用於協議編解碼的工具庫。它和XML或者JSON差不多
ProtoBuf開發者指南大全(Google Protocol Buffer協議)
目錄 1 概覽 1.1 什麼是protocol buffer 1.2 他們如何工作 1.3 為什麼不用XML? 1.4 聽起來像是為我的解決方案,如何開始? 1.5 一點歷史 2 語言指導 2.1 定義一個訊息型別 2.2 值型別 2.3 可選欄位與預設值 2.4