Ted
Ted

Reputation: 87

Protobuf getAllFields() performance

We are using protobuf as our messaging, and each message, we loop thru the set fields, and do something with it.

We loop it using

    for ( final Map.Entry<Descriptors.FieldDescriptor, Object> entry : msg.getAllFields().entrySet()) {
            FieldDescriptor field = entry.getKey();
            Object value = entry.getValue();

Under profiler, we found that this GetAllFields uses most of the time, and I did some research, and it looks like there is no other way.

I know that we can use do something like this:

    for ( final FieldDescriptor field : msg.getDescriptorForType().getFields()) {
        if (!msg.hasField(field)){
            continue;
        }
        Object value = message.getField(field);

But getDescriptorForType returns all the fields rather than just the set ones.

Does anyone know of another better performing way to loop thru the fields? I believe the problem with getAllFields are creating a new map each time, and also reflection. Can i force it to use Trove map inside rather than a regular hashmap?

Thanks.

Upvotes: 4

Views: 2992

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45151

getAllFields() is part of Protobuf's reflection interface (not to be confused with Java's reflection). Protobuf reflection is, alas, quite slow -- it's essentially like using an interpreted language rather than a compiled one.

If you need your code to be fast, the way to do it is to call the generated-code methods directly. Unfortunately this can be tedious if you're doing something repetitive to every field. One thing you might consider is writing a code generator plugin for protoc to auto-generate the repetitive code (much like protoc generates code for the protobuf classes themselves). For more on how to do that, see the docs on descriptor.proto.

Upvotes: 5

Related Questions