Protobuf getAllFields() 性能

Ted*_*Ted 4 java performance protocol-buffers

我们使用 protobuf 作为消息传递,对于每条消息,我们都会循环遍历设置的字段,并用它做一些事情。

我们使用循环它

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

在profiler下,我们发现这个GetAllFields用的最多,我研究了一下,貌似没有其他办法了。

我知道我们可以使用这样做:

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

但 getDescriptorForType 返回所有字段而不仅仅是设置的字段。

有谁知道另一种更好的循环遍历字段的方法?我相信 getAllFields 的问题是每次创建一个新地图以及反射。我可以强制它在内部使用 Trove map 而不是常规的 hashmap 吗?

谢谢。

Ken*_*rda 5

getAllFields()是 Protobuf 反射接口的一部分(不要与 Java 的反射混淆)。唉,Protobuf 反射相当慢——它本质上就像使用解释型语言而不是编译型语言。

如果您需要代码速度快,那么方法是直接调用生成代码的方法。不幸的是,如果您在每个领域都做重复的事情,这可能会很乏味。您可能考虑的一件事是编写一个代码生成器插件来protoc自动生成重复代码(就像protoc为 protobuf 类本身生成代码一样)。有关如何执行此操作的更多信息,请参阅descriptor.proto 上的文档