Protocol Buffers的應用

1. Protocol Buffers的介紹

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages – Java, C++, or Python. You can even update your data structure without breaking deployed programs that are compiled against the “old” format.(摘自Protocol Buffers官網)

protocol buffers是google提供的一種將結構化數據進行序列化和反序列化的方法,其優點是語言中立,平臺中立,可擴展性好,目前在google內部大量用于數據存儲,通訊協議等方面。Protocol Buffers在功能上類似XML,但是序列化后的數據更小,解析更快,使用上更簡單。用戶只要按照proto語法在.proto文件中定義好數據的結構,就可以使用Protocol Buffers提供的工具(protoc)自動生成處理數據的代碼,使用這些代碼就能在程序中方便的通過各種數據流讀寫數據。PB目前支持Java, C++和Python3種語言。另外,Protocol Buffers還提供了很好的向后兼容,即舊版本的程序可以正常處理新版本的數據,新版本的程序也能正常處理舊版本的數據。

Protocol Buffers具有以下特點:

  1. 平臺無關、語言無關
  2. 高性能 比XML塊20-100倍
  3. 體積小 比XML小3-10倍
  4. 使用簡單
  5. 兼容性好

2、message的編碼特點

Protocol Buffers 之所以解析速度快、所占體積小,很大程度上是由它序列化的編碼特點來決定的。

2.1 Base 128 Varints

Protocol Buffers采用了Base 128 Varints來變長編碼整數:

  1. 變長編碼的整數,它可能包含多個byte,對于每個byte的8位,其中后7位表示數值,最高的一位表示是否還有還有另一個byte,0表示沒有,1表示有;
  2. 越前面的byte表示數值的低位,越后面的byte表示數值的高位;

例子:
300 varints 編碼為:1010 1100 0000 0010
解釋如下:
300的2進制編碼為:0001 0010 1100
按照剛才的規則,高低位顛倒,截取最后的7為放在第一個byte,則第一byte為1010 1100(其中最高位1表示,后續還有byte);接著剩下的內容放到第二個byte,為0000 0010(其中最高位0表示,后續無byte,這個數到這里截止了)。
于是,合在一起為 1010 1100 0000 0010;

2.2 Key-Value

如前所述,Protocol Buffers的message是一系列的key-value對,在二進制數據中,使用varints數字(包含了別名以及屬性類型信息)來作為key,進而通過由PB編譯器生成的代碼來構造以及解析數據。
Protocol Buffers將 key編碼成下面的結構:
X YYYY ZZZ
其中:最高位X表示是否還有后續的byte來編碼數字別名;YYYY用于編碼別名,定義了多余16個屬性,則需要用到額外的byte,所以出現頻率高的字段應當取1-16的別名);ZZZ表示這個字段的類型,PB支持的屬性的對應規則如下表:

TypeMeaningUsed For
0Varintint32, int64, uint32, uint64, sint32,sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages,packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, floa

表2:PB 屬性對應規則
例子:
required int32 a=1; 在應用中給a賦值150 ,序列化后08 96 01

  • 08代表的是key 0 0001 000, 最高位為0,表示這個key為一個byte,中間四位表示a的數字別名,最后三位表示a的屬性類型;
  • 96 01代表的是value,二進制為:1001 0110 0000 0001
    → 001 0110 000 0001(去掉最高位)
    → 22 + 1*2^7 = 150

2.3 Zig-Zag

采用varints的方式編碼有符號的整數,效率比較差,因為負數的最高位是1,這樣就導致了情況類似于編碼一個很大的數。

為了解決這個問題,Protocol Buffers定義了sint32/sint64屬性,他們采用了“之字形”(ZigZag)編碼的方式,將負數編碼成正數,交替進行。看了下表就很好理解了:

Signed OriginalEncoded As
00
-11
12
-23
21474836474294967294
21474836484294967295

表3:Zig-Zag編碼規則

利用這個方式,可以有效地節省存儲空間,也能提高解析效率。了解了以上內容,對于其他數據類型的編碼,也是很好理解的,大家可以參考官方文檔,這里不做詳述。

3.為什么不用XML?

ProtocolBuffer擁有多項比XML更高級的串行化結構數據的特性,ProtocolBuffer:

· 更簡單

· 小3-10倍

· 快20-100倍

· 更少的歧義

· 可以方便的生成數據存取類

例如,讓我們看看如何在XML中建模Person的name和email字段:

<person>
<name>John Doe</name>
<email>jdoe@example.com</email>
</person>

對應的ProtocolBuffer報文則如下:

#ProtocolBuffer的文本表示
#這不是正常時使用的二進制數據
person {
name: "John Doe"
email: "jdoe@example.com"
}

當這個報文編碼到ProtocolBuffer的二進制格式( http://code.google.com/apis/protocolbuffers/docs/encoding.html )時(上面的文本僅用于調試和編輯),它只需要28字節和100-200ns的解析時間。而XML的版本需要69字節(除去空白)和5000-10000ns的解析時間。

當然,操作ProtocolBuffer也很簡單:

cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

而XML的你需要:

cout << "Name: "
<< person.getElementsByTagName("name")->item(0)->innerText()
<< endl;
cout << "E-mail: "
<< person.getElementsByTagName("email")->item(0)->innerText()
<< end;

當然,ProtocolBuffer并不是在任何時候都比XML更合適,例如ProtocolBuffer無法對一個基于標記文本的文檔建模,因為你根本沒法方便的在文本中插入結構。另外,XML是便于人類閱讀和編輯的,而ProtocolBuffer則不是。還有XML是自解釋的,而 ProtocolBuffer僅在你擁有報文格式定義的 .proto 文件時才有意義。

?

相關文章:

.net自帶二進制序列化,XML序列化和ProtoBuf序列化的壓縮對比

WCF服務上應用protobuf

玩轉Protocol Buffers

Beetle使用Protobuf.net進行對象序列化傳輸

Google Protocol Buffer 的使用和原理

Protocol Buffers and WCF http://blogs.msdn.com/b/dmetzgar/archive/2011/03/29/protocol-buffers-and-wcf.aspx

Protobuf-net: the unofficial manual http://www.codeproject.com/Articles/642677/Protobuf-net-the-unofficial-manual

Working with Protobuf WCF Services http://www.drdobbs.com/windows/working-with-protobuf-wcf-services/240159282?pgno=1

?

轉載于:https://www.cnblogs.com/shanyou/archive/2013/02/11/2910174.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260004.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260004.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260004.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編程提高:一天一道編程題

1.文本操作 逆轉字符串——輸入一個字符串&#xff0c;將其逆轉并輸出。 拉丁豬文字游戲——這是一個英語語言游戲。基本規則是將一個英語單詞的第一個輔音音素的字母移動到詞尾并且加上后綴-ay&#xff08;譬如“banana”會變成“anana-bay”&#xff09;。可以在維基百科上了…

android自驗簽名證書,沒有以前的互聯網連接,無法驗證Android自簽名證書

使用SSL基礎架構&#xff1a;我們有一個有效的客戶端/服務器設置,其中Android版本4.2和4.4的手機充當客戶端,必須通過其自簽名SSL證書驗證服務器.問題&#xff1a;只要設備在嘗試連接之前至少有一次互聯網訪問權限,服務器證書驗證就會起作用.但是,如果執行恢復出廠設置且設備直…

asp.net緩存(二)

ASP.NET頁面局部緩存 有時緩存整個頁面是不現實的&#xff0c;因為頁的某些部分可能在每次請求時都需要變化。在這些情況下&#xff0c;只能緩存頁的一部分。顧名思義&#xff0c;頁面部分緩存是將頁面部分內容保存在內存中以便響應用戶請求&#xff0c;而頁面其他部分內容則為…

學習C# - Hello,World!

第一天學C#,開始學著寫一些學習筆記&#xff0c;看了一下傳智播客的視頻&#xff0c;按照傳智播客的教學順序&#xff0c;開始學習。 class Program{static void Main(string[] args){Console.WriteLine("Hello World!");//自動添加回車換行Console.Write("Hell…

android獲取button寬度,android – 如何獲得Button的高度和寬度

我創建了一系列按鈕.現在我想找到按鈕的高度和寬度,為此我使用了getWidth()和getHeight().但問題是它總是返回0.為什么會發生這種情況&#xff1f;我發送了我的代碼,請檢查是否有任何問題.int x,y;LinearLayout layoutVertical (LinearLayout) findViewById(R.id.liVLayout);L…

java執行sql列名無效_嵌套異常是java.sql.SQLException:無效的列名ORACLE

我嘗試在Java中使用JdbcTemplate執行以下oracle查詢&#xff1a;select RESOURCE_IDfrom REPRO_PRINTING_JOBwhere (USER_ID? and PRINTING_CENTER_ID?)group by RESOURCE_IDunion allselect RESOURCE_IDfrom REPRO_PRINTING_JOB_OLDwhere (USER_ID? and PRINTING_CENTER_ID…

(七)Maven使用的最佳實踐

這里說一下在使用Maven過程中不是必須的&#xff0c;但十分有用的幾個實踐&#xff0c;關鍵時刻或許能解決您的問題。 1.設置MAVEN_OPTS環境變量 通常需要設置MAVEN_OPTS的值為-Xms128m -Xmx512m&#xff0c;因為Java默認的最大可用內存往往不能夠滿足Maven運行的需要&#xff…

android beam傳輸速率,無線網絡的速率為何不能達到最大值

1、無線速率可以達到最大值&#xff0c;只是發送速率和傳輸流量是兩個概念&#xff0c;通俗點講&#xff0c;無線的發送速率是把信號以指定速率發出去(信號好的時候以高速率發&#xff0c;信號差的時候以低速率發)。傳輸流量是指單位時間內傳輸的數據量&#xff0c;大部分用戶關…

【SMTP 補錄 Apache服務】

【補錄&#xff0c;續】1.【配置空殼郵件接受】【mta】【前置&#xff1a;在/etc/named.rfc1912.zones 添加一個可以接受郵件的域hxl.org&#xff08;與你數據庫中寫的向對應&#xff09;,這個域的所在ip就是你機子的&#xff0c;因為要從你的機子轉發】 【配置該機的vim/etc/…

image打開rgb16 qt_QT中顯示圖像數據

一般圖像數據都是以RGBRGBRGB……字節流的方式(解碼完成后的原始圖像流)&#xff0c;我說成字節流&#xff0c;那就表明R&#xff0c;G&#xff0c;B的值各占一個字節&#xff0c;在編程時表示的就是unsigned char * data。我們先來看一下QT中的QImage對象。在加載data數據前&a…

開啟chrome默認支持ipv6

在快捷方式后面的屬性后面輸入 --enable-ipv6 以下為轉載&#xff1a; [轉載]chrome開啟或關閉IPV6方法 (2012-05-27 17:54:06) 轉載▼ 標簽&#xff1a; 轉載 分類&#xff1a; 技術 原文地址&#xff1a;chrome開啟或關閉IPV6方法作者&#xff1a;余鯤濤 chrome和firefox都是…

Nginx安裝部署

轉&#xff1a;http://www.cnblogs.com/zhuhongbao/archive/2013/06/04/3118061.html Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器&#xff0c;也是一個 IMAP/POP3/SMTP 代理服務器。 Nginx 是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開…

android ble 連續讀寫,Android BLE實現對藍牙的讀寫

【實例簡介】通過修改官方的demo實現對藍牙的讀寫操作&#xff0c;詳細http://blog.csdn.net/chenfengdejuanlian/article/details/45787123【實例截圖】【核心代碼】BluetoothLe_demo0└── BluetoothLe_demo0├── AndroidManifest.xml├── bin│ ├── AndroidManife…

一分鐘經理人

原創2016-12-0858沈劍 零、緣起近期公司再做管理者培訓&#xff0c;偶老大推薦了一本薄薄的《一分鐘經理人》&#xff0c;斯賓塞.約翰遜&#xff0c;花了1小時讀完有感&#xff0c;沉淀一篇閱讀筆記&#xff0c;故有此文。一、前言常見經理人有兩類&#xff1a;&#xff08;1&a…

python寫機器人程序_用Python寫的一個多線程機器人聊天程序

本人是從事php開發的, 近來想通過php實現即時通訊(兼容windows)。后來發現實現起來特別麻煩&#xff0c; 就想到python。聽說這家伙在什么地方都能發揮作用。所以想用python來做通訊模塊。。。所以主要學習pythonn的多線程和tcp連接。但是沒有用過python&#xff0c; 所有在學習…

[轉] 前端中的MVC

MVC是一種設計模式&#xff0c;它將應用劃分為3個部分&#xff1a;數據&#xff08;模型&#xff09;、展現層&#xff08;視圖&#xff09;和用戶交互&#xff08;控制器&#xff09;。其中&#xff1a; M - MODEL&#xff08;模型&#xff09; V - VIEW&#xff08;視圖&…

ipoo3可以用鴻蒙,iqooneo3支持無線充電嗎_iqooneo3可以無線充電嗎

iqoo neo3在不高的價格上還保證了自己的品質&#xff0c;有很高的性能&#xff0c;很不錯的屏幕。那么這款手機可以支持無線充電嗎&#xff1f;小編為大家介紹關于iqoo neo3的充電方面。1.iqoo neo3可以支持無線充電嗎iQOO Neo3 配備了 44W 超級閃充&#xff0c;屬于小刀&#…

紅帽Linux故障定位技術詳解與實例(1)

紅帽Linux故障定位技術詳解與實例(1) 2011-09-28 14:26 圈兒 BEAREYES.COM 我要評論(0) 字號&#xff1a;T | T在線故障定位就是在故障發生時, 故障所處的操作系統環境仍然可以訪問&#xff0c;故障處理人員可通過console, ssh等方式登錄到操作系統上&#xff0c;在shell上執行…

u2020 華為_華為5G網管U2020常用MML命令(很實用)

激活小區ACT NRCELL:;ACT NRDUCELL:;去激活小區DEA NRCELL:;DEA NRDUCELL:;查詢小區靜態信息LST NRCELL:;LST NRDUCELL:;查詢小區動態信息DSP NRCELL:;DSP NRDUCELL:;修改幀偏置MOD GNODEBPARAM:FRAMEOFFSET70728;修改子幀配比、時隙結構MOD NRDUCELL:NRDUCELLID0,DUPLEXMODECE…

Struts2中過濾器,攔截器,監聽器他們之間有什么區別?

1、攔截器是基于java反射機制的&#xff0c;而過濾器是基于函數回調的。2、過濾器依賴與servlet容器&#xff0c;而攔截器不依賴與servlet容器。3、攔截器只能對Action請求起作用&#xff0c;而過濾器則可以對幾乎所有請求起作用。4、攔截器可以訪問Action上下文、值棧里的對象…