Protocol Buffersでの通信はjsonと比べて早いのか。

## protocol buffersとは
API通信などで、Jsonのようなテキスト形式で通信を行わずに、protocol buffersはバイナリ形式で通信を行います。
proto file(事前にスキーマを定義するファイル)から、サーバー側とクライアント側に、シリアライズ・デシリアライズ用のファイルを書き出し、それらを利用してデータの送受信を行います。

バイナリー形式で通信を行う分、データサイズが小さいためパフォーマンスがいいとされています。
そこで、jsonと比べてどのくらいレスポンスが早くなるのかを試してみました。

## 準備
データ量の少ないものと多いものの２種類のAPIを用意しました。

一つ目は、都道府県のリストを返すGETのAPIです。
prefecturesをkeyにして、その中に47個のitemが入っています。

```json

//レスポンス例
{  
   "prefectures":[  
      {  
         "id":1,
         "name":"北海道",
         "romaji":"hokkaido"
      },
      {  
         "id":2,
         "name":"青森県",
         "romaji":"aomori"
      },
            ...
      {  
         "id":46,
         "name":"鹿児島県",
         "romaji":"kagoshima"
      },
      {  
         "id":47,
         "name":"沖縄県",
         "romaji":"okinawa"
      }
   ]
}

```

二つ目は、membersをkeyにして、1000のitemを返すGETのAPIです。

```json

//レスポンス例
{  
   "members":[  
      {  
         "id":1,
         "age":25,
         "eye_color":"blue",
         "name":"Rebekah Horne",
         "gender":"female",
         "company":"REMOTION",
         "email":"rebekahhorne@remotion.com",
         "phone":"+1 (883) 507-2758",
         "address":"375 Moultrie Street, Kohatk, Nevada, 5200",
         "about":"Commodo ullamco minim Lorem non voluptate aliqua dolor dolor minim ea enim eiusmod aliquip consequat. Voluptate aute consequat ipsum officia culpa occaecat occaecat qui enim sit cillum id deserunt ut. Occaecat est magna esse dolor veniam mollit exercitation. Sunt sit incididunt amet velit veniam veniam ea ipsum amet aliqua consequat. Deserunt aute velit aliquip ex exercitation labore laboris in ut duis consectetur aliquip amet. Duis adipisicing laboris nulla mollit irure deserunt voluptate est. Ullamco enim exercitation ipsum Lorem.\r\n",
         "greeting":"Hello, Rebekah Horne"
      },
      {  
         "id":2,
         "age":40,
         "eye_color":"brown",
         "name":"Gay Espinoza",
         "gender":"female",
         "company":"TRIPSCH",
         "email":"gayespinoza@tripsch.com",
         "phone":"+1 (809) 551-3700",
         "address":"846 Bassett Avenue, Mammoth, Indiana, 912",
         "about":"Consequat ut aute mollit consequat aute et enim ipsum. Consectetur est sunt magna aliquip consequat qui aliquip nisi magna est. Voluptate aliquip labore aliqua ipsum quis et velit qui minim. Deserunt officia officia voluptate occaecat laboris in ea culpa aliquip culpa sit tempor.\r\n",
         "greeting":"Hello, Gay Espinoza"
      },
      {  
         "id":3,
         "age":23,
         "eye_color":"brown",
         "name":"Miller Dawson",
         "gender":"male",
         "company":"COMBOGENE",
         "email":"millerdawson@combogene.com",
         "phone":"+1 (814) 435-3532",
         "address":"284 Strong Place, Independence, Pennsylvania, 8816",
         "about":"Dolore cupidatat et consectetur pariatur ex non nisi et anim magna ullamco aute laborum. Ut laboris veniam proident minim ut in dolor officia dolor amet et sunt duis. Dolore aliquip dolor incididunt elit labore cupidatat velit cillum eu aute reprehenderit. Cupidatat et ipsum ut aute laboris ea veniam labore sunt. Enim ad pariatur ut sint non ad veniam Lorem adipisicing magna culpa amet.\r\n",
         "greeting":"Hello, Miller Dawson"
      },
            ...
      {  
         "id":998,
         "age":26,
         "eye_color":"brown",
         "name":"Katherine Kinney",
         "gender":"female",
         "company":"EMTRAC",
         "email":"katherinekinney@emtrac.com",
         "phone":"+1 (966) 464-2346",
         "address":"568 Chester Street, Villarreal, Oklahoma, 5307",
         "about":"Nulla ea fugiat cillum adipisicing irure magna sit consectetur non ea nulla. Pariatur qui eiusmod veniam aute sunt quis Lorem minim. Aliquip Lorem est commodo est nisi irure ex et. Dolor nulla exercitation non ut aute id nisi adipisicing tempor ad ad in. Reprehenderit do adipisicing et velit labore elit laborum exercitation elit Lorem est velit. Excepteur sit nostrud eiusmod dolor amet sunt.\r\n",
         "greeting":"Hello, Katherine Kinney"
      },
      {  
         "id":999,
         "age":25,
         "eye_color":"blue",
         "name":"Tamika Frazier",
         "gender":"female",
         "company":"EZENT",
         "email":"tamikafrazier@ezent.com",
         "phone":"+1 (818) 422-2321",
         "address":"449 Greene Avenue, Waumandee, Oregon, 6996",
         "about":"Cupidatat ex ex esse nulla proident deserunt nisi mollit ad. Aliquip sint proident laborum ullamco duis enim eiusmod do voluptate do. Voluptate nostrud reprehenderit qui aliqua nulla. Est ut eu ipsum qui cillum. Duis laboris labore consectetur exercitation anim fugiat anim et id officia. Pariatur eiusmod ea sint est velit consequat ad sit dolore sunt incididunt laboris non ad. Velit mollit non quis adipisicing.\r\n",
         "greeting":"Hello, Tamika Frazier"
      },
      {  
         "id":1000,
         "age":27,
         "eye_color":"brown",
         "name":"Elena Frazier",
         "gender":"female",
         "company":"EZENT",
         "email":"elenafrazier@ezent.com",
         "phone":"+1 (845) 403-3185",
         "address":"398 Greene Avenue, Waumandee, North Dakota, 5735",
         "about":"Aute in veniam adipisicing fugiat nisi pariatur nulla irure nostrud duis enim eiusmod occaecat. Cupidatat mollit ipsum incididunt consectetur elit magna proident est reprehenderit anim mollit eu. Officia mollit sunt velit mollit incididunt sit commodo laboris tempor sunt. Occaecat amet esse excepteur exercitation labore fugiat irure Lorem veniam quis.\r\n",
         "greeting":"Hello, Elena Frazier"
      }
   ]
}

```

clientサイドはAndroidを使って実装しました。
計測時間はAPIを叩いてから、レスポンスをclient側のモデルにパースするまでの時間を計測しました。

## 検証１　PrefecturesAPI （データ量少なめ）

先程のprefecturesのAPIをそれぞれjsonパターンとprotocol buffersパターンで10回叩いてみて、比べてみました。

| json response |proto response |result |
|:-----------------|:------------------|:------------------|
| 965ms             | 879ms             |json > proto (-86ms)|
| 390ms             | 373ms             |json > proto (-17ms)|
| 537ms             | 535ms             |json > proto (-2ms)|
| 308ms             | 319ms             |json < proto (+11ms)|
| 373ms             | 372ms             |json > proto (-1ms)|
| 369ms             | 388ms             |json < proto (+19ms)|
| 336ms             | 338ms             |json < proto (+2ms)|
| 326ms             | 324ms             |json > proto (-2ms)|
| 384ms             | 393ms             |json < proto (+9ms)|
| 553ms             | 542ms             |json > proto (-11ms)|

平均で、protocol buffersでの通信のほうが7.8ms早い結果になりました。

## 検証１　MembersAPI （データ量多め）

先程のmembersのAPIをそれぞれjsonパターンとprotocol buffersパターンで10回叩いてみて、比べてみました。

| json response |proto response |result |
|:-----------------|:------------------|:------------------|
| 3215ms           | 3234ms            |json < proto (+19ms)|
| 2802ms           | 2739ms            |json > proto (-63ms)|
| 2254ms           | 2152ms            |json > proto (-102ms)|
| 1915ms           | 1836ms            |json > proto (-79ms)|
| 2028ms           | 1955ms            |json > proto (-73ms)|
| 2133ms           | 2094ms            |json > proto (-39ms)|
| 2748ms           | 2471ms            |json > proto (-277ms)|
| 2093ms           | 1977ms            |json > proto (-116ms)|
| 2099ms           | 2002ms            |json > proto (-97ms)|
| 2039ms           | 1987ms            |json > proto (-52ms)|

平均で、protocol buffersでの通信のほうが87.9ms早い結果になりました。

## 結論
jsonよりもはやりprotocol buffersのほうが早い結果になりました。
ただ、データ量が少ない場合はそんなに変わらないかもです。。。

今回使用したコードは以下に上がっているので、ぜひ見てみてください

Protoファイル
https://github.com/TakuSemba/cheddar

サーバーサイド　【golang】
https://github.com/TakuSemba/camembert

クライアントサイド　【kotlin】
https://github.com/TakuSemba/gouda

protocol buffersでの導入方法は以下の記事を書いたので、ぜひ見てみてください。

Protocol BuffersでAPI通信 サーバー編【golang】
http://qiita.com/takusemba/items/05a4431114f0c6fee3d9

Protocol BuffersでAPI通信 Android編
http://qiita.com/takusemba/items/d40eec9dedb163c0ec9d