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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions