0
0

More than 3 years have passed since last update.

ProtocとWireで生成されるJavaファイルとバイトコードのサイズを比較してみた

Last updated at Posted at 2021-03-18

GradleでProtocol Bufferを使う時にはGoogleのProtobuf Plugin for GradleWireのGradle Pluginが主流だと思いますが、それぞれのコンパイラ(protoc/wire)で生成されるJavaファイル(およびKotlinファイル)のサイズと、さらにそれをJVMバイトコードにコンパイルした時のファイルサイズを比較してみました。

きっかけはSquare社のIntroducing Wire Protocol Buffersという記事で、Protocol Bufferの実装をprotocからwireに変えたらメソッドが10,000くらい減ったと書いてあり、ファイルサイズでいうとどのくらい減るのかが気になったためです。

For the Square Register app, generated Protocol Buffer code was taking up a large chunk of our method space. By switching to Wire, we removed almost 10,000 methods from our application and gained a lot of breathing room to add new features

コンパイル対象のprotoファイル

コンパイル対象とするproroファイルは以下です。

Persion.proto
syntax="proto3";

option java_package = "com.example.protobufsample";

// This is Person
message Person {
  string first_name = 1;
  string last_name = 2;
  repeated string family_names = 3;
}

protoc/wireのコンパイルで生成されたJavaファイルの比較

コンパイラ 生成ファイル ファイルサイズ
protoc Person.java 20K
Wire Person.java 6.4K
Wire Person.kt 5.1K

protocがGoogleのProtocol Bufferの実装で、WireはそのままWireですが、見ての通り、wireの方が3~4倍ファイルサイズが小さいですね。
ファイルサイズのみならず、可読性の面でも、Wireの方が良い印象。

JVMバイトコードのファイルサイズの比較

実際にJVMのメモリに乗る時のサイズでも一応見比べてみるために、今度はさっきのjava/kotlinファイルを、classファイルに変換してみます。

元のコンパイラ java/kotlinファイル classファイル ファイルサイズ(合計)
protoc Person.java Person\$1.class, Person\$Person\$Builder.class, Person\$Person.class, Person\$PersonOrBuilder.class, Person.class 17K
Wire Person.java Person\$Builder.class, Person\$ProtoAdapter_Person.class, Person.class 9.1K
Wire Person.kt Person\$Companion\$ADAPTER\$1.class, Person\$Companion.class, Person.class 13K

先のjava/kotlinの時にはWireかつKotlinの組み合わせ一番小さかったですが、さらにJVMバイトコードになると、まぁ予想通り、WireかつJavaファイルの組み合わせが一番小さかったです。

なお補足ですが、JVMバイトコードへの変換はそれぞれ以下のようにやりました。
バージョンの箇所は適宜ご自分の環境に合わせてください。

// protocで生成されたjavaファイルをclassファイルに変換
javac -cp path/to/protobuf-java-3.0.0.jar Person.java
// Wireで生成されたjavaファイルをclassファイルに変換
javac -cp path/to/wire-compiler-3.6.1-jar-with-dependencies.jar Person.java
// Wireで生成されたKotlinファイルをclassファイルに変換
kotlinc -jvm-target 1.8 -cp path/to/wire-compiler-3.6.1-jar-with-dependencies.jar Person.kt

まとめ

protocやWire自体のサイズ、あるいは依存ライブラリも含めたサイズがどっちが大きいかまでは調べてないですが、少なくとも生成されるJVMバイトコードのサイズで比較する限りは、Gradleでprotoファイルをコンパイルする場合、WireでJavaファイルにコンパイルすることで場合によってはprotocより50%減できるかもしれないですね。もし可読性も重視するのでしたら、WireとKotlinの組み合わせが良きかなと思います、それでも70%ほど減らせる可能性があるので。

参考:
- https://developer.squareup.com/blog/introducing-wire-protocol-buffers/
- https://square.github.io/wire/wire_vs_protoc/
- https://search.maven.org/search?q=g:com.squareup.wire%20AND%20a:wire-compiler
- https://search.maven.org/artifact/com.google.protobuf/protobuf-java/3.15.0/bundle

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0