Skip to content

Parsing time too long while using WireTypeAdapterFactory #3460

@Zogesh

Description

@Zogesh

Environment

  • Android (Kotlin)
  • Wire version: (add your version)
  • Gson / Moshi version: (add versions)
  • Proto generated using wire-compiler
  • App supports both binary protobuf and JSON responses

📌 Summary
I have an Android app that has used protobuf + wire-compiler–generated Kotlin data classes for a long time. Proto decoding is extremely fast, as expected.

We also added an option to return JSON responses for the same proto schema. To support this, I registered WireTypeAdapterFactory with Gson so I can decode JSON into the same generated Wire messages.

However, after switching to JSON responses, parsing time increased massively (multiple-fold slowdown) compared to protobuf. Even moderately nested messages take much longer to read, causing visible UI delays and frame drops.

I wrote a custom implementation of WireTypeAdapterFactory (mainly to change enum handling), and even after caching all RuntimeMessageAdapter instances, performance is still very slow.

I also tested with Moshi + WireJsonAdapterFactory, and while slightly faster, it still suffers from the same fundamental cost — JSON decoding of Wire messages is an order of magnitude slower than protobuf decoding.

🔍 What I Have Already Tried
✔️ 1. Caching RuntimeMessageAdapter instances
I verified that RuntimeMessageAdapter.create() is not being called repeatedly.
All adapters are cached in a global map. → No major improvement.

✔️ 2. Custom TypeAdapter with optimized field lookup
I built a custom implementation of WireTypeAdapterFactory that includes:
Cached field maps (nameToField)
Pre-bound setter lambdas to avoid reflection inside FieldBinding.set()
Inline fast paths for primitives (avoid TypeAdapter.read() for boolean/int/double/string)

✔️ 3. Switching from Gson → Moshi
Tried WireJsonAdapterFactory:

But, unfortunately none of this worked.

Example Proto (dummy simplified version)

message WidgetResponse {
    WidgetConfig widget_config = 1;
    oneof widgets {
        Widget1 widget_1 = 2;
        Widget2 widget_2 = 3;
    }
}

message WidgetConfig {
    WidgetType widget_type = 1;
}

enum WidgetType {
    WIDGET_TYPE_1 = 0;
    WIDGET_TYPE_2 = 1;
}

message Widget1 {
    string title = 1;
}

message Widget2 {
    string title = 1;
    string subtitle = 2;
}

Please help me out in fixing this problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions