麻豆精品无码av,欧美1区2区,久久中文字幕乱码人妻,亚洲欧美另类少妇精品,在线看黄射,69pao高清,九九九久久久国产精品,子操大逼1234区,九九爱99热精品

1
點贊
0
評論
0
轉載
收藏

經驗分享|大數(shù)據傳輸利器ProtoBuf使用指南

在大數(shù)據時代,人們每天都要面對海量數(shù)據,如何存儲和傳輸這些數(shù)據成為了一大難題。Protocol Buffers(簡稱ProtoBuf)是Google公司開發(fā)的一種與語言和平臺無關的、可擴展的、序列化結構數(shù)據的方法,可用于(數(shù)據)通信協(xié)議、數(shù)據存儲等。用戶可以利用ProtoBuf定義數(shù)據的結構,然后使用特殊生成的源代碼輕松地在各種數(shù)據流中使用各種語言來編寫和讀取結構數(shù)據,甚至還可以在不破壞由舊數(shù)據結構編譯的已部署程序的基礎上更新數(shù)據結構。ProtoBuf目前有兩個版本,分別是proto2和proto3,其中最新版本的proto3提供了對C++、C#、Dart、Go、Java、Python、Rust等多種語言的支持。ProtoBuf性能優(yōu)異,目前已經被廣泛應用于QQ、微信等主流通訊工具。

圖片

ProtoBuf的使用主要分為兩步,首先需要使用者在.proto文件中定義消息類型,然后使用protoc編譯器根據.proto文件生成相應語言的代碼。

圖1展示了一個簡單的示例。我們定義了一個搜索請求消息,每一個搜索請求都包含了查詢字符query、搜索請求返回的頁面數(shù)量page_number和每頁中的結果數(shù)量result_per_page。該示例的第一行聲明了我們正在使用proto3。如果沒有該行,ProtoBuf編譯器將默認使用proto2。需注意,該行一定要位于文件的第一非空且非注釋行。

圖片

圖1 ProtoBuf搜索請求消息示例

該請求消息示例中的SearchRequest消息定義了三個字段,每一個字段都有一個定義類型、一個字段名稱以及字段編號。ProtoBuf提供了大量標準數(shù)據類型,其中常用的有:double、float、int32、int64、bool、string、bytes等。此外,message中每個字段都可以指定一個修飾符,proto3默認使用singular修飾符,表示可以有0個或者1個該字段,但不能超過一個。除此之外,還有一種repeated修飾符,表示對應的字段在message中可以有任意數(shù)量個,包括0個。

圖片

圖2 ProtoBuf嵌套類型字段示例

message中包含的字段類型除了默認支持類型外,還支持嵌套類型,即字段類型為所定義的其他message類型。如圖2所示,我們在SearchResponse消息中包含了一個repeated修飾的Result類型字段。

圖片圖3 ProtoBuf多消息定義示例

在同一個.proto文件中可以定義多個message類型,如圖3所示,我們在該.proto文件中定義了SearchRequest和SearchResponse兩個消息類型。與此同時,ProtoBuf也可以在不同的.proto文件中定義message,然后通過import語法進行引入。為了防止出現(xiàn)命名沖突的問題,.proto文件將通過引入package語法解決命名沖突的問題。

在解析消息時,如果使用singular修飾符的字段不包含數(shù)據,那么ProtoBuf會給對應字段設定默認值。對于string類型的字段,其默認值為空字符串;對于bytes類型的字段,其默認值為空字節(jié);對于bool類型的字段,其默認值為false;對于數(shù)字類型的字段,其默認值為0;對于enums類型的字段,其默認值為第一個定義的枚舉類型。此外,對于使用repeated修飾符的字段,其默認值為對應語言的空列表。需要特別注意的是,proto2支持指定字段默認值,但proto3已經取消了該語法。

在代碼注釋上,ProtoBuf采用與C/C++相同的 // 和 /**/ 注釋格式,如圖4所示。

圖片

圖4 ProtoBuf注釋示例

最后,執(zhí)行圖5中的編譯指令后,我們就可以在相應的目錄下找到生成的對應語言的代碼文件。該文件包含了對不同message進行定義、修改、訪問等操作的方法。圖5中的IMPORT_PATH表示import文件的搜索目錄,--cpp_out、--java_out、--python_out、--go_out、--ruby_out、--objc_out、--csharp-out、--php_out分別表示生成的C++、Java、Python、GO、Ruby、Objective-C、C#、PHP目標代碼存放目錄。以C++為例,執(zhí)行該編譯指令后會在目標目錄生成file.pb.h和file.pb.cc兩個文件,file.pb.h中聲明了相關類和方法,file.pb.cc中定義了相關類和方法。

圖片

圖5 ProtoBuf編譯指令示例

俗話說得好:“光說不練假把式。”接下來,我們就拿ProtoBuf與目前最常見的同類型工具JSON進行對比,看看它到底強在哪里。JSON作為一種輕量級的基于文本的編碼方法,也可以用來存儲結構化數(shù)據,經常被應用于Client/Server端的通訊中。在對比實驗中,我們選擇由騰訊公司發(fā)布的、使用性能較好的RapidJSON,基于C++編程語言進行測試。

.proto文件如下

圖片

ProtoBuf測試代碼如下:

void Protobuf(int times)
{
    Person person;
    person.set_id(1000000);
    person.set_name("XIAOMING");
    person.add_phone_num(1008611);
    person.add_phone_num(1001011);

    string person_string;

    cout << "[Protobuf]" << endl << "--編碼耗時--" << endl;
    cout << "編碼次數(shù): " << times << "   數(shù)據長度: " << person.SerializeAsString().size() << endl;

    auto start = chrono::steady_clock::now();
    for (size_t index = 0; index < times; ++index)
    {
        person_string = person.SerializeAsString();
    }
    auto end = chrono::steady_clock::now();
    cout << "用時: " << chrono::duration<double,std::milli>(end - start).count() << " ms" << endl;

    cout << "--解碼測試--" << endl;
    cout << "解碼次數(shù): " << times << "   數(shù)據長度: " << person.SerializeAsString().size() << endl;

    start = chrono::steady_clock::now();
    for (size_t index = 0; index < times; ++index)
    {
        person.ParseFromString(person_string);
    }
    end = chrono::steady_clock::now();
    cout << "用時: " << chrono::duration<double,std::milli>(end - start).count() << " ms" << endl;
}

JSON測試代碼如下:

void Json(int times)
{
    Document doc;
    doc.Parse("{}");
    doc.AddMember("id", 1000000, doc.GetAllocator());
    doc.AddMember("name", "XIAOMING", doc.GetAllocator());
    Value phone_number(kArrayType);
    phone_number.PushBack(1008611, doc.GetAllocator());
    phone_number.PushBack(1001011, doc.GetAllocator());

    const char *person_string;
    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    doc.Accept(writer);
    
    person_string = buffer.GetString();

    cout << "[JSON]" << endl << "--編碼耗時--" << endl;
    cout << "編碼次數(shù): " << times << "   數(shù)據長度: " << buffer.GetSize() << endl;

    auto start = chrono::steady_clock::now();
    for (size_t index = 0; index < times; ++index)
    {
        buffer.Clear();
        writer.Reset(buffer);
        doc.Accept(writer);
    }
    auto end = chrono::steady_clock::now();
    cout << "用時: " << chrono::duration<double,std::milli>(end - start).count() << " ms" << endl;

    cout << "--解碼測試--" << endl;
    cout << "解碼次數(shù): " << times << "   數(shù)據長度: " << buffer.GetSize() << endl;

    start = chrono::steady_clock::now();
    for (size_t index = 0; index < times; ++index)
    {
        doc.Parse(person_string);
    }
    end = chrono::steady_clock::now();
    cout << "用時: " << chrono::duration<double,std::milli>(end - start).count() << " ms" << endl;
}

測試結果如下:

圖片

圖片

從上述測試結果可以看出,整體上ProtoBuf的編碼效率為RapidJSON的2.99倍,其解碼效率為RapidJSON的3.29倍,而且存儲空間僅為RapidJSON的68.75%。當編碼和解碼頻率較低時,二者耗時差異不明顯;但當編碼和解碼頻率較高時,ProtoBuf可以節(jié)省大量的時間。當數(shù)據量較大時,使用ProtoBuf可以有效降低空間需求,在網絡傳輸場景下,可以降低對網絡的要求,提高數(shù)據傳輸效率。

總體來說,ProtoBuf序列化和反序列的性能都比較高,編碼后的數(shù)據大小也不錯,編程模式簡單易學,同時擁有較為完備的文檔和示例,有需要的小伙伴放心用起來吧!

圖片

研究團隊介紹

圖片

智能算法研究中心(原智能算法實驗室,2018年與2020年更名)主要承擔國內外重要智能算法類的研究課題,以算法與軟件工具包的形式,根據國內外企業(yè)、科研與教育機構等單位在智能信息處理方面的需求,解決相關技術難點問題,并從中培養(yǎng)國際化算法研究型人才與算法工程化人才。

實驗室必修課

實驗室精神

圖片

-END-

總編:黃翰

責任編輯:袁中錦

文字:劉一鳴

圖片:劉一鳴

校稿:何莉怡

時間:2021年12月30日

聲明:本內容系學者網用戶個人學術動態(tài)分享,不代表平臺立場。

SCHOLAT.com 學者網
免責聲明 | 關于我們 | 聯(lián)系我們
聯(lián)系我們:
返回頂部
乌兰察布市| 临汾市| 佛学| 五指山市| 调兵山市| 托克逊县| 嘉禾县| 镇雄县| 沂南县| 收藏| 五大连池市| 景谷| 内黄县| 台中县| 莱州市| 靖边县| 农安县| 孟州市| 洛扎县| 昌黎县| 永修县| 怀集县| 万全县| 龙岩市| 平乐县| 禄劝| 宝清县| 南城县| 鲁甸县| 青河县| 抚顺市| 桂东县| 潮安县| 攀枝花市| 平乡县| 朝阳县| 开原市| 高淳县| 丰县| 林口县| 和林格尔县|