青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

FlatBuffers 體驗

轉(zhuǎn)載自:http://www.race604.com/flatbuffers-intro/


1. 背景

最近在項目中需要使用一種高效數(shù)據(jù)序列化的工具。碰巧在幾篇文章中都提到了FlatBuffers 這個庫。特別是 Android 性能優(yōu)化典范第四季1中兩個對比圖,讓我對它產(chǎn)生濃厚的興趣。如下:

(注:圖片來自1

可見,FlatBuffers 幾乎從空間和時間復(fù)雜度上完勝其他技術(shù),我決定詳細調(diào)研一下此技術(shù)。

FlatBuffers 是一個開源的跨平臺數(shù)據(jù)序列化庫,可以應(yīng)用到幾乎任何語言(C++, C#, Go, Java, JavaScript, PHP, Python),最開始是 Google 為游戲或者其他對性能要求很高的應(yīng)用開發(fā)的。項目地址在 GitHub 上。官方的文檔在 這里

本文將介紹一下我使用 FlatBuffers 的一些感受,希望對想要了解或者使用 FlatBuffers 的同學(xué)有一點幫組。

2. FlatBuffer 的優(yōu)點

FlatBuffer 相對于其他序列化技術(shù),例如 XML,JSON,Protocol Buffers 等,有哪些優(yōu)勢呢?官方文檔的說法如下:

  1. 直接讀取序列化數(shù)據(jù),而不需要解析(Parsing)或者解包(Unpacking):FlatBuffer 把數(shù)據(jù)層級結(jié)構(gòu)保存在一個扁平化的二進制緩存(一維數(shù)組)中,同時能夠保持直接獲取里面的結(jié)構(gòu)化數(shù)據(jù),而不需要解析,并且還能保證數(shù)據(jù)結(jié)構(gòu)變化的前后向兼容。
  2. 高效的內(nèi)存使用和速度:FlatBuffer 使用過程中,不需要額外的內(nèi)存,幾乎接近原始數(shù)據(jù)在內(nèi)存中的大小。
  3. 靈活:數(shù)據(jù)能夠前后向兼容,并且能夠靈活控制你的數(shù)據(jù)結(jié)構(gòu)。
  4. 很少的代碼侵入性:使用少量的自動生成的代碼即可實現(xiàn)。
  5. 強數(shù)據(jù)類性,易于使用,跨平臺,幾乎語言無關(guān)。

官方提供了一個性能對比表如下:

(注:來自 官方文檔

在做 Android 開發(fā)的時候,JSON 是最常用的數(shù)據(jù)序列化技術(shù)。我們知道,JSON 的可讀性很強,但是序列化和反序列化性能卻是最差的。解析的時候,JSON 解析器首先,需要在內(nèi)存中初始化一個對應(yīng)的數(shù)據(jù)結(jié)構(gòu),這個事件經(jīng)常會消耗 100ms ~ 200ms2;解析過程中,要產(chǎn)生大量的臨時變量,造成 Java 虛擬機的 GC 和內(nèi)存抖動,解析 20KB 的數(shù)據(jù),大概會消耗 100KB 的臨時內(nèi)存2。FlatBuffers 就解決了這些問題。

3. 使用方法

簡單來說,F(xiàn)latBuffers 的使用方法是,首先按照使用特定的 IDL 定義數(shù)據(jù)結(jié)構(gòu) schema,然后使用編譯工具 flatc 編譯 schema 生成對應(yīng)的代碼,把生成的代碼應(yīng)用到工程中即可。下面詳細介紹每一步。

首先,我們需要得到 flatc,這個需要從源碼編輯得到。從 GitHub 上 Clone 代碼,

$ git clone https://github.com/google/flatbuffers 

在 Mac 上,使用 Xcode 直接打開 build/Xcode/ 里面項目文件,編譯運行,即可在項目根目錄生成我們需要的 flatc 工具。也可以使用 cmake 編輯,例如在 Linux 上,運行如下命令即可:

$ cmake -G "Unix Makefiles"
$ make

首先要使用 FlatBuffers 的 IDL 定義好數(shù)據(jù)結(jié)構(gòu) Schema,編寫 Schema 的詳細文檔在 這里。其語法和 C 語言類似,比較容易上手。我們這里引用一個簡單的例子2,假設(shè)數(shù)據(jù)結(jié)構(gòu)如下:

class Person {  
    String name;
    int friendshipStatus;
    Person spouse;
    List<Person>friends;
}

編寫成 Schema 如下,文件名為 Person.fbs

// Person schema

namespace com.race604.fbs;

enum FriendshipStatus: int {Friend = 1, NotFriend}

table Person {  
  name: string;
  friendshipStatus: FriendshipStatus = Friend;
  spouse: Person;
  friends: [Person];
}

root_type Person;

然后,使用 flatc 可以把 Schema 編譯成多種編程語言,我們僅僅討論 Android 平臺,所以把 Schema 編譯成 Java,命令如下:

$ ./flatc --java Person.fbs 

在當(dāng)前目錄生成如下文件:

.
└── com
    └── race604
        └── fbs
            ├── FriendshipStatus.java
            └── Person.java

Person 類有響應(yīng)的函數(shù)直接獲取其內(nèi)部的屬性值,使用非常簡單:

Person person = ;  
// 獲取普通成員
String name = person.name();  
int friendshipStatus = person.friendshipStatus();  
// 獲取數(shù)組
int length = person.friendsLength()  
for (int i = 0; i < length; i++) {  
    Person friends = person.friends(i);
    
}

下面我們來構(gòu)建一個 Person 對象,名字是 "John",其配偶(spouse)是 "Mary",還有兩個朋友,分別是 "Dave" 和 "Tom",實現(xiàn)如下:

private ByteBuffer createPerson() {  
    FlatBufferBuilder builder = new FlatBufferBuilder(0);
    int spouseName = builder.createString("Mary");
    int spouse = Person.createPerson(builder, spouseName, FriendshipStatus.Friend, 0, 0);

    int friendDave = Person.createPerson(builder, builder.createString("Dave"),
            FriendshipStatus.Friend, 0, 0);
    int friendTom = Person.createPerson(builder, builder.createString("Tom"),
            FriendshipStatus.Friend, 0, 0);

    int name = builder.createString("John");
    int[] friendsArr = new int[]{ friendDave, friendTom };
    int friends = Person.createFriendsVector(builder, friendsArr);

    Person.startPerson(builder);
    Person.addName(builder, name);
    Person.addSpouse(builder, spouse);
    Person.addFriends(builder, friends);
    Person.addFriendshipStatus(builder, FriendshipStatus.NotFriend);

    int john = Person.endPerson(builder);
    builder.finish(john);

    return builder.dataBuffer();
}

基本方法就是通過 FlatBufferBuilder 工具,往里面填寫數(shù)據(jù),詳細的寫法可以參考官方文檔3。可見,其實寫法略顯繁瑣,不太直觀。

4. 基本原理

如官方文檔的介紹,FlatBuffers 就像它的名字所表示的一樣,就是把結(jié)構(gòu)化的對象,用一個扁平化(Flat)的緩沖區(qū)保存,簡單的來說就是把內(nèi)存對象數(shù)據(jù),保存在一個一維的數(shù)組中。借用 Facebook 文章2的一張圖如下:

可見,F(xiàn)latBuffers 保存在一個 byte 數(shù)組中,有一個“支點”指針(pivot point)以此為界,存儲的內(nèi)容分為兩個部分:元數(shù)據(jù)和數(shù)據(jù)內(nèi)容。其中元數(shù)據(jù)部分就是數(shù)據(jù)在前面,其長度等于對象中的字段數(shù)量,每個 byte 保存對應(yīng)字段內(nèi)容在數(shù)組中的索引(從支點位置開始計算)。

如圖,上面的 Person 對象第一個字段是 name,其值的索引位置是 1,所以從索引位置 1 開始的字符串,就是 name 字段的值 "John"。第二個字段是 friendshipStatus,其索引值是 6,找到值為 2, 表示 NotFriend。第三個字段是 spouse,也一個 Person 對象,索引值是 12,指向的是此對象的支點位置。第四個字段是一個數(shù)組,圖中表示的數(shù)組為空,所以索引值是 0。

通過上面的解析,可以看出,F(xiàn)latBuffers 通過自己分配和管理對象的存儲,使對象在內(nèi)存中就是線性結(jié)構(gòu)化的,直接可以把內(nèi)存內(nèi)容保存或者發(fā)送出去,加載“解析”數(shù)據(jù)只需要把 byte 數(shù)組加載到內(nèi)存中即可,不需要任何解析,也不產(chǎn)生任何中間變量。

它與具體的機器或者運行環(huán)境無關(guān),例如在 Java 中,對象內(nèi)的內(nèi)存不依賴 Java 虛擬機的堆內(nèi)存分配策略實現(xiàn),所以也是跨平臺的。

5. 使用建議

通過前面的體驗,F(xiàn)latBuffers 幾乎秒殺了 JSON,我也嘗試使用到現(xiàn)在的項目中,但是最后還是放棄了,下面說說 FlatBuffers 的幾點缺點:

  1. FlatBuffers 需要生成代碼,對代碼有侵入性;
  2. 數(shù)據(jù)序列化沒有可讀性,不方便 Debug;
  3. 構(gòu)建 FlatBuffers 對象比較麻煩,不直觀,特別是如果對象比較復(fù)雜情況下需要寫大段的代碼;
  4. 數(shù)據(jù)的所有內(nèi)容需要使用 Schema 嚴(yán)格定義,靈活性不如 JSON。

我最后在項目中放棄是因為上面的第 4 點,因為在我的項目中,數(shù)據(jù)結(jié)構(gòu)變化很大,不方便使用 Schema 完全定義。話又說回來,F(xiàn)latBuffers 這么多好處,還是很吸引我的,可能會在其他的項目中嘗試。

所以,在什么情況下選擇使用 FlatBuffers 呢?個人感覺需要滿足以下幾點:

  1. 項目中有大量數(shù)據(jù)傳輸和解析,使用 JSON 成為了性能瓶頸;
  2. 穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)定義。

參考資料:

  1. http://geek.csdn.net/news/detail/50692 

  2. https://code.facebook.com/posts/872547912839369/improving-facebook-s-performance-on-android-with-flatbuffers/ 

  3. http://google.github.io/flatbuffers/flatbuffersguidetutorial.html 

  4. http://frogermcs.github.io/flatbuffers-in-android-introdution/ 

posted on 2016-11-15 22:39 楊粼波 閱讀(547) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区动漫| 国产日韩精品一区二区三区在线| 午夜精品电影| 欧美freesex8一10精品| 久久精品亚洲一区二区三区浴池| 欧美激情一区二区久久久| 久久久综合网站| 国产伦精品一区二区三区四区免费| 亚洲国产精品热久久| 国内激情久久| 午夜亚洲激情| 亚洲欧美影音先锋| 欧美性感一类影片在线播放| 91久久夜色精品国产九色| 亚洲激情一区二区| 久久亚洲图片| 欧美国产日本韩| 亚洲激情不卡| 欧美华人在线视频| 亚洲第一精品夜夜躁人人躁 | 欧美福利小视频| 欧美成人黑人xx视频免费观看| 国产一区二区三区成人欧美日韩在线观看 | 国产免费成人在线视频| 一区二区三区高清在线| 一区二区三区视频在线看| 欧美国产日本在线| 亚洲精品一区二区三区福利| 一本色道久久综合精品竹菊 | 亚洲黄色影院| 欧美国产亚洲另类动漫| 亚洲黄网站在线观看| 亚洲激情视频在线观看| 欧美黄色一级视频| 亚洲看片一区| 亚洲欧美日韩人成在线播放| 国产麻豆日韩欧美久久| 欧美伊人久久久久久午夜久久久久 | 香蕉久久夜色精品国产| 国产欧美精品一区aⅴ影院| 午夜精品久久久久久久久| 久久午夜电影网| 亚洲国语精品自产拍在线观看| 欧美xxx在线观看| 亚洲日本成人| 亚洲欧美一区二区三区久久| 国产午夜亚洲精品不卡| 久久中文字幕一区| 亚洲精品视频在线| 欧美一级理论片| 亚洲高清在线精品| 欧美三区在线观看| 久久国产成人| 日韩视频永久免费| 久久久噜噜噜久久中文字幕色伊伊| 在线成人中文字幕| 国产精品v欧美精品v日本精品动漫 | 免费成人在线观看视频| 99在线观看免费视频精品观看| 国产精品家教| 麻豆精品一区二区av白丝在线| 99热免费精品在线观看| 久久精品网址| 99精品国产热久久91蜜凸| 国产欧美二区| 欧美日韩精品中文字幕| 欧美在线网址| 一区二区三区日韩| 亚洲大胆美女视频| 久久久久九九九| 亚洲在线观看免费| 亚洲国内欧美| 狠狠综合久久| 国产精品久久久久99| 免费一级欧美在线大片| 亚洲欧美在线一区二区| 亚洲美女在线国产| 欧美第十八页| 久久久国产精品一区二区三区| 夜夜嗨av色综合久久久综合网| 国模精品娜娜一二三区| 国产精品日韩专区| 欧美天天视频| 欧美精品日韩| 欧美韩日一区二区| 久久综合色天天久久综合图片| 亚洲欧美另类在线| 一区二区三区欧美日韩| 最近中文字幕mv在线一区二区三区四区 | 欧美亚洲不卡| 欧美日韩三区| 欧美精品一区在线| 欧美a级一区| 暖暖成人免费视频| 久久天天躁狠狠躁夜夜爽蜜月| 欧美一级黄色网| 先锋a资源在线看亚洲| 亚洲一区免费| 亚洲午夜性刺激影院| 亚洲美女黄网| 在线一区亚洲| 亚洲一区成人| 午夜免费在线观看精品视频| 中文日韩在线视频| 中文在线一区| 亚洲欧美精品一区| 午夜在线精品偷拍| 欧美在线一区二区| 久久国产主播| 久久精精品视频| 久久久久一区二区| 久久中文字幕导航| 欧美福利一区| 国产精品vip| 国产日本欧美一区二区三区在线| 国产欧美一区二区精品性 | 韩日欧美一区二区三区| 狠久久av成人天堂| 在线观看日韩av电影| 亚洲国产精品久久久久久女王| 亚洲精品久久嫩草网站秘色| 亚洲精品小视频在线观看| 日韩网站免费观看| 亚洲欧美日本另类| 久久不射中文字幕| 欧美18av| 日韩一级免费观看| 欧美亚洲视频| 欧美成人有码| 国产精品亚洲产品| 在线观看日韩av| 在线亚洲精品| 久久精品99国产精品日本| 欧美+亚洲+精品+三区| 亚洲乱码久久| 香蕉免费一区二区三区在线观看| 久久久久99| 欧美日韩一区二区免费在线观看 | 亚洲国产精品第一区二区三区 | 亚洲福利精品| 亚洲一区三区电影在线观看| 久久久在线视频| 日韩午夜电影在线观看| 久久国产黑丝| 欧美性做爰毛片| 在线观看欧美成人| 亚洲欧美一区二区激情| 免费一级欧美片在线播放| 日韩一级裸体免费视频| 久久久国际精品| 国产精品日韩精品| 亚洲九九精品| 久久精选视频| 在线亚洲欧美| 欧美www视频在线观看| 国产日韩一级二级三级| 9国产精品视频| 能在线观看的日韩av| 亚洲免费婷婷| 欧美日韩hd| 亚洲国产精品福利| 久久久久综合网| 亚洲一区二区视频在线观看| 欧美69wwwcom| 国产亚洲精品bt天堂精选| 一区二区三区国产在线| 欧美高清视频免费观看| 欧美一站二站| 国产精品一区二区男女羞羞无遮挡 | 欧美mv日韩mv国产网站app| 国产乱码精品一区二区三区av| 亚洲精品永久免费精品| 免费观看日韩| 欧美在线啊v| 国产乱码精品一区二区三区av| 亚洲视屏在线播放| 亚洲精品社区| 欧美日韩爆操| 99爱精品视频| 亚洲精品国产精品久久清纯直播 | 亚洲片区在线| 欧美ed2k| 免费精品视频| 亚洲国产精品黑人久久久| 蜜臀av国产精品久久久久| 欧美一区二区三区的| 国产亚洲一本大道中文在线| 欧美亚洲在线观看| 亚洲欧美另类在线| 国产无一区二区| 久久人人爽人人爽| 久久中文字幕导航| 亚洲黄页视频免费观看| 欧美激情在线有限公司| 欧美成人一区在线| 99精品国产在热久久婷婷| 99国产精品久久久久久久久久 | 久久琪琪电影院| 久久久99久久精品女同性| 伊人成人在线视频|