如何在 protobuf 消息中建模 Java 原始 int[] 数组

Posted

技术标签:

【中文标题】如何在 protobuf 消息中建模 Java 原始 int[] 数组【英文标题】:How to model Java primitive int[] array in protobuf message 【发布时间】:2018-11-30 23:13:35 【问题描述】:

我是 Google 协议缓冲区的新手,并试图通过 protobuf 消息在 java 中对原始 int[] 数组进行建模。

目前我正在使用这个 proto 文件:

syntax = "proto3";
package protobuf;

message primitiveArrayMsg 
    repeated int32 data = 1;

它编译成带有List<Integer> 数据结构的java 类,而不是原始int 的数组。

/**
 * <code>repeated int32 data = 1;</code>
 */
java.util.List<java.lang.Integer> getDataList();

我的应用程序必须保存数百万个 int 值,为了节省内存,我决定使用 int 而不是 Integer。 有没有办法在具有int[] 数据结构的java 类中编译protobuf 消息描述?

不幸的是,我在Protocol Buffers Language Guide (proto3) 中一无所获。在How to add a int array in protobuf message 中也提出了类似的问题,我尝试过,但显然问题作者正在寻找ArrayList&lt;Integer&gt;,因此答案对我没有帮助。

如果没有对此的支持,你能推荐我一个比装箱到Integer 和使用List&lt;Integer&gt; 更节省内存的方法吗?

【问题讨论】:

你确定它实际上是这样存储列表的吗?例如,getData(int) 将返回未装箱的值。如果它存储装箱值,将值拆箱以将其返回给您,那么您将不得不再次装箱,这将是低效的。 getDataList() 可能只是 int[] 的“装箱视图”,但必须返回 List&lt;Integer&gt;,因为这是 List 所能提供的全部。 【参考方案1】:

协议缓冲区消息是not designed to handle large messages。

即使在使用 proto3 时整数默认为 efficiently packed,运行时内存中仍需要大量 Integer 对象(除非实际使用的不同值很少,在这种情况下,可以重新使用 Integer 对象) - 使用)。

如果您确实必须为此使用 Protocol Buffer 消息,另一种选择是在编码/解码时将 int 数组转换为字节数组格式和从字节数组格式转换。

【讨论】:

以上是关于如何在 protobuf 消息中建模 Java 原始 int[] 数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中读取 protobuf 消息时出现异常

检查 protoBuf 中是不是存在消息类型

java protobuf如何从int创建ByteString

流式传输 protoBuf 消息的设计模式

如何确定protobuf中的消息类型,以便我可以使用该类型.parsefrom(byte [])

Protobuf语法介绍