コード生成でGsonをMoshiより高速化する - Islands in the byte stream の続きです。
GitHub - gfx/StaticGson: Static Gson binding library with annotation processing
三行まとめ
- StaticGsonはannotation processingでコード生成してGsonを高速化する拡張で、結果はLoganSquareより少し遅い程度
- 欠点はメソッド数+バイナリサイズのオーバーヘッド
- 利点はGsonと互換性の高さ。モデルにアノテーションをつけてGson初期化でオプションを一つ与えるだけ
解説
リフレクションで処理していたところをコード生成にして高速化する手法は思ったより効果ありそうだな、ということでjcenterにリリースしました。以下のように依存指定すると使えます。
dependencies { apt 'com.github.gfx.static_gson:static-gson-processor:0.9.4' compile 'com.github.gfx.static_gson:static-gson:0.9.4' }
使い方は簡単で、シリアライズ対象のモデルに @JsonSerializable
をつけて:
@JsonSerializable public class Book { // ... }
GsonBuilderにtype adapter factoryを与えるだけ:
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(StaticGsonTypeAdapterFactory.newInstance())
.create();
setDateFormat()
などのGsonBuilder
のoptionはだいたい効きますが、FieldNamingPolicy
など一部のリフレクションの絡む機能は別途@JsonSerializable
に与える必要があります。READMEにもあるとおりこんな感じ。
このシリアライズ名はコンパイル時に決定されるので、proguard避けのために@SerializedName
を設定する必要はありません。速度よりもこっちのほうが個人的には嬉しい。
// LOWER_CASE_WITH_UNDERSCORES: 名前は各パーツをlower caseにしてアンダースコアで繋げるものとする @JsonSerializable( fieldNamingPolicy = FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES ) public class User { public String firstName; // serialized to "first_name" public Stirng lastName; // serialized to "last_name" }
benchmarkはLoganSquare のものに手を加えてStaticGson対応させたもので測定してこんな感じ。Web APIのパースが多いだろうからパースに関する結果を載せています。Gsonよりも30%くらいは高速で、Jacksonより速くてLoganSquareより遅いという水準ですね。すでにGsonを使っているアプリに手軽に適用できるし、Gsonのオプションもほぼそのまま有効なので、導入が低コストという意味ではいいかもしれません。新規で使うならLoganSquareのほうが高速ではありますが、様々な場合にちゃんと対応できるかどうかまでは調べてないのでそこはよくわかりません。
LganSquare Benchimark with StaticGson v0.9.3. #android pic.twitter.com/kCpPWMDDhv
— FUJI Goro (@__gfx__) 2016年3月15日