ProtoBufとJSONのパフォーマンスの比較

シリアル化:ProtoBufとJSONの比較!
はじめに

ProtoBufは、構造化データを効率的に保存および読み取るためにGoogleチームによって開発されたツールです。構造化データとは、文字通り表現されているように、特定の構造を持つデータです。たとえば、電話帳には多くのレコードがあり、各レコードには名前、ID、電子メール、電話などが含まれています。この構造が繰り返されます。

同様

XMLとJSONを使用してこのような構造化データを格納することもできますが、ProtoBufで表されるデータはより効率的で、データをより小さく圧縮できます。

原理

ProtoBufは、ProtoBufコンパイラを使用して、プログラミング言語に関連しない一意の.protoサフィックスデータ構造ファイルを各プログラミング言語(Java、C / C ++、Python)の特定のクラスファイルにコンパイルし、各プログラミング言語のサポートを介してコンパイルします。 Googleが提供ライブラリlibはAPIを呼び出すことができます。(プロト構造の記述方法については、ドキュメントを自分で参照できます)

ProtoBufコンパイラのインストール

Mac:brew install protobuf

例えば

1.最初にプロトファイルを作成します

message.proto

syntax = "proto3";

message Person {
    int32 id = 1;
    string name = 2;

    repeated Phone phone = 4;

    enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }

    message Phone {
        string number = 1;
        PhoneType type = 2;
    }
}

コードをコピーします。2。Java
プロジェクト
作成し、protoファイルをsrc / main / protoフォルダーに配置します。

3. protoファイルをJavaバージョンにコンパイルし
、コマンドラインを使用してsrc / mainディレクトリにcdします。

ターミナル実行コマンド:protoc --java_out = ./ java ./proto/*.proto

対応するJavaクラスがsrc / main / javaに生成されていることがわかります。

4. ProtoBufサポートライブラリのJavaバージョンに
依存します。これは、依存関係を使用するためにGradleを使用する栗です。

実装 'com.google.protobuf:protobuf-java:3.9.1'
コードの
コピー5.JavaオブジェクトをProtoBufデータに変換します

Message.Person.Phone.Builder phoneBuilder = Message.Person.Phone.newBuilder();
Message.Person.Phone phone1 = phoneBuilder
        .setNumber("100860")
        .setType(Message.Person.PhoneType.HOME)
        .build();
Message.Person.Phone phone2 = phoneBuilder
        .setNumber("100100")
        .setType(Message.Person.PhoneType.MOBILE)
        .build();
Message.Person.Builder personBuilder = Message.Person.newBuilder();
personBuilder.setId(1994);
personBuilder.setName("XIAOLEI");
personBuilder.addPhone(phone1);
personBuilder.addPhone(phone2);

Message.Person person = personBuilder.build();
long old = System.currentTimeMillis();
byte[] buff = person.toByteArray();
System.out.println("ProtoBuf 编码耗时:" + (System.currentTimeMillis() - old));
System.out.println(Arrays.toString(buff));
System.out.println("ProtoBuf 数据长度:" + buff.length);

コードをコピーします
。6。ProtoBufデータをJavaオブジェクトに変換し直します。

System.out.println("-开始解码-");
old = System.currentTimeMillis();
Message.Person personOut = Message.Person.parseFrom(buff);
System.out.println("ProtoBuf 解码耗时:" + (System.currentTimeMillis() - old));
System.out.printf("Id:%d, Name:%s\n", personOut.getId(), personOut.getName());
List<Message.Person.Phone> phoneList = personOut.getPhoneList();
for (Message.Person.Phone phone : phoneList)
{
    System.out.printf("手机号:%s (%s)\n", phone.getNumber(), phone.getType());
}

コードのコピー
比較

ProtoBufの利点を反映するために、同じ構造のJavaクラスを作成し、JavaオブジェクトをJSONデータに変換してProtoBufと比較しました。JSONコンパイルライブラリはGoogleが提供するGSONライブラリを使用し、JSONコードの一部は投稿されず、結果は直接表示されます

結果の比較

1回実行

[JSONエンコード開始]
JSONエンコード1回、時間:22ms
JSONデータ長:106-
デコード開始-JSON
デコード1回、時間:1ms

[ProtoBufエンコード開始]
ProtoBufエンコード1回、時間:32ms
ProtoBufデータ長:34-
デコード
開始-ProtoBufデコード1回、時間:3ms
コードをコピーして
10回実行

[JSONエンコード開始]
JSONエンコード10回、時間:22ms
JSONデータ長:106-
デコード開始-JSON
デコード10回、時間:4ms

[ProtoBufエンコード開始]
ProtoBufエンコード10回、時間:29ms
ProtoBufデータ長:34-
デコード
開始-ProtoBufデコード10回、時間:3ms
コピーコード
実行100回

[JSONエンコード開始]
JSONエンコード100回、時間:32ms
JSONデータ長:106-
デコード開始-JSON
デコード100回、時間:8ms

[ProtoBufエンコード開始]
ProtoBufエンコード100回、時間:31ms
ProtoBufデータ長:34-
デコード
開始-ProtoBufデコード100回、時間:4ms
コピーコード
実行1000回

[JSONエンコード開始]
JSONエンコード1000回、時間:39ms
JSONデータ長:106-
デコード開始-JSON
デコード1000回、時間:21ms

[ProtoBufエンコード開始]
ProtoBufエンコード1000回、時間:37ms
ProtoBufデータ長:34-
デコード
開始-ProtoBufデコード1000回、時間:8ms
コピーコード
実行10,000回

[JSONエンコード開始]
JSONエンコード10000回、時間:126ms
JSONデータ長:106-
デコード開始-JSON
デコード10000回、時間:93ms

] [Protobufエンコード開始
protobufエンコード10000、処理済み:49ms
protobufデータ長:34-デコード
開始
-protobufデコード10,000、処理済み:23ms
コード
コピーして100,000を実行

【JSONエンコード開始】JSONエンコード
100000回、時間:248ms
JSONデータの長さ106-
デコード開始-JSON
デコード100000回、時間:180ms

] [Protobufは
protobufコーディング100,000のエンコードを開始し、処理済み:51ms
protobufデータ長:34-デコードを
開始
-protobufデコード100,000、処理済み:58ms
コードの
概要をコピー

エンコードとデコードのパフォーマンス
上記の栗は単純なサンプリングです。実際、私の実験によれば、

頻度が1,000未満の場合、ProtoBufのエンコードおよびデコードのパフォーマンスはJSONに匹敵し、JSONよりもさらに劣ります。
回数は2,000回を超え、ProtoBufのエンコードとデコードのパフォーマンスはJSONよりもはるかに高くなっています。
数が100,000を超える場合、ProtoBufのコーデックパフォーマンスは明らかであり、JSONのパフォーマンスよりもはるかに高くなります。
メモリ
はProtoBufのメモリの34を占めますが、JSONは106に達しますが、ProtoBufのメモリはJSONの1/3しか占めません。

終わり

実際、この実験には最適化する必要のあることがたくさんあります。この種の大まかなテストでも、ProtoBufの利点を確認できます。

互換性があります

新しいフィールド

ニックネームフィールドをプロトファイルに追加します

Javaファイルを生成する

古いプロトバイト配列データを使用して、オブジェクトに変換します

Id:1994、名前:XIAOLEI携帯電話番号:100860(HOME)携帯電話番号:100100(MOBILE)getNickname =

その結果、変換を成功させることができます。

フィールドを削除

プロトファイルの名前フィールドを削除します

Javaファイルを生成する

古いプロトバイト配列データを使用して、オブジェクトに変換します

ID:1994、名前:null携帯電話番号:100860(HOME)携帯電話番号:100100(MOBILE)

その結果、変換を成功させることができます。

おすすめ

転載: blog.csdn.net/qq_17010193/article/details/114391387
おすすめ