gRPCのiOS実機環境における速度検証について

こんにちは。A.R.T.でクライアントエンジニアをしている藤尾です。

前回、UnityプロジェクトでのgRPC導入方法についてという記事で、iOSとAndroid環境を含めたgRPCの導入方法について紹介させていただきました。

今回はその環境でのiOSでの速度検証を行いましたので、紹介させていただきたいと思います。

検証環境

アプリボットではゲームのサーバー開発には、主にJSONでのREST APIを用いています。

そこで、gRPCとRESTでのレイテンシを比較します。

サーバー環境

速度検証に利用したサーバー環境は以下のとおりです。

また、通信に用いたデータは、以下のprotoで定義されます。

message ExampleCommonMessage {
    int32 id = 1;
}
message ExampleMessage {
    double double = 1;
    float float = 20;
    int32 int = 21;
    int64 long = 22;
    bool boolean = 31;
    string string = 32;
    ExampleEnum enum = 34;
    map<string, int32> map = 37;
}
message ExampleRequest {
    int32 id = 1;
    ExampleCommonMessage common = 2;
}
message ExampleResponse1 {
    int32 id = 1;
    ExampleCommonMessage common = 2;
    ExampleMessage message = 3;
    string description = 4;
}
message ExampleResponse1Array {
    repeated ExampleResponse1 response = 1;
}
service ExampleService {
    rpc ExampleResponse1List (ExampleRequest) returns (ExampleResponse1Array);
}

上記のExampleService.ExampleResponlise1Listでは以下の通りレスポンスを返します。

  • ExampleResponse1内の要素及び孫要素全てに値を設定する
  • ExampleResponse1Arrayの中にExampleResponse1を指定した件数返す

ここでgRPCでは上記のデータをProtocolBuffersで通信し、RESTでは上記のデータをJSONで通信するものとします。

クライアント環境について

1APIについて、リクエストをシリアライズし(ただし今回は空のリクエストになるため、0件)、レスポンスを受け取り、デシリアライズが完了するまでの時間を計測します。

これを1000回試行し、その平均を取りました。

この検証を、APIのレスポンス量を変更して(ExampleResponlise1Arrayの件数を変化させることで)、レイテンシの変化をみます。

また、クライアントで利用しているソフトウェアのバージョンはそれぞれ以下のとおりです。

名前 バージョン
Unity 2018.1.9f1
gRPC 1.12.0
ProtocolBuffers 3.5.1
.NET 4.6
端末 iPhone7
OS Version 10.3.2
Json Utility 1.12.0

計測結果

以下が、検証結果になります。

レスポンスサイズ

はじめに、JSONとProtocolBuffersでのレスポンスのサイズを比較します。単位はbyteです。

形式 10 100 300 500
JSON 1705 17894 55580 93298
ProtocolBuffers 701 7321 23859 40561

500件で、約44%のレスポンスサイズとなることがわかりました。

処理時間

処理全体では以下の通りになります。ただし、単位はミリ秒(ms)です。

形式 10 100 300 500
gRPC 17 46 113 177
JSON 73 90 132 158

Screen Shot 2018-11-21 at 14.41.13.png

データ量が小さい場合は、gRPCのほうが早いですが、徐々にRESTが早くなっています。

そこで、デシリアライズ時間に絞って計測をしてみます。

デシリアライズ時間

形式 10 100 300 500
ProtocolBuffers 4 32 94 156
JSON 4 19 43 69

Screen Shot 2018-11-21 at 14.32.26.png

JsonUtilityによるJSONが、gRPCに比べて高速だということが検証でわかりました。

この検証から、通信そのものの速度についてはgRPCがREST(HTTP)と比べて高速ですが、

デシリアライズ処理については、端末についてはJsonが高速であることがわかりました。

まとめ

上記の検証結果から、以下のことがわかりました。

  • 通信そのものの速度については、gRPCのほうがREST(HTTP)よりも高速である
  • デシリアライズについては、特に件数が増えるにつれ、JSONのほうが高速になる

そこで上記の特性上、現在gRPCを使用して開発中のタイトルであるSEVEN’s CODEでは、以下のようにgRPCを利用していく予定です。

  • 通信はgRPCを採用する
  • 通信量が小さい箇所では、ProtocolBuffersをそのまま利用する
  • 通信量が大きい箇所(例えばマスタデータなどの配列)では、そのデータをJsonでシリアライズした文字列としてProtocolBuffers上では通信し、受信後にその文字列をJsonとしてデシリアライズして利用する