Protobuf getAllFields () performance

We use protobuf as our messaging, and every message we loop through the given 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();

      

In the profiler, we found that this GetAllFields is using most of the time and I have done some research and it looks like there is no other way.

I know we can use something like this:

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

      

But getDescriptorForType returns all fields, not just set ones.

Does anyone know of another more efficient way to loop through fields? I believe the problem with getAllFields is creating a new map every time and also the reflection. Can I force it to use the Pipe map internally and not a regular hash map?

Thank.

+3


source to share


1 answer


getAllFields()

is part of the Protobuf reflection interface (not to be confused with Java reflection). Reflection protobuf is, alas, rather slow - essentially, it's 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 methods of the generated code directly. Unfortunately, this can be tedious if you are doing something repetitive for each field. You might consider writing a code generator plugin protoc

to automatically generate repetitive code (just as it protoc

generates code for the protobuf classes themselves). For details on how to do this, see the docs on the .proto descriptor .

+2


source







All Articles