protocol-buffers - protobuf 消息中的最大字段数
问题描述
协议缓冲区的官方文档https://developers.google.com/protocol-buffers/docs/proto3说 protobuf 消息中字段的最大字段数是 2^29-1。但是为什么会有这个限制?请问有人可以详细解释一下吗?我是新手。
我阅读了这个问题的答案,为什么 2^29-1 是协议缓冲区中最大的键。但我没有澄清
解决方案
编码协议缓冲区中的每个字段都有一个以实际编码值为前缀的标头(称为键或标签)。编码规范定义了这个键:
流式消息中的每个键都是一个 varint,其值为 (field_number << 3) | 线型——换句话说,数字的最后三位存储线型。
这里的规范说标签是一个 varint,其中前 3 位用于编码线路类型。varint 可以编码一个 64 位的值,因此只要继续这个定义,限制就会是2^61-1
.
除此之外,语言指南将其缩小到最大 32 位值。
您可以指定的最小字段数是 1,最大的是 2^29 - 1,即 536,870,911。
没有给出这样做的原因。我只能推测这背后的原因:
人为限制,因为没有人期望消息具有这么多字段。只需考虑将具有这么多字段的消息放入内存中。
由于键是 varint,它不仅仅是原始缓冲区中接下来的 4 个字节,而是可变长度的字节(读取 varint32 的 Java 代码)。每个字节有 7 位实际数据和 1 位指示是否到达末尾。出于性能原因,限制范围被认为是更好的选择。
由于 proto3 是协议缓冲区的第 3 个版本,因此 proto1 或 proto2 可能将标记定义为 varint32。为了保持向后兼容性,这个限制在今天的 proto3 中仍然有效。
推荐阅读
- weblogic - 从 weblogic 服务器中删除集群设置
- php - App\Models\ 必须返回一个关系实例
- r - 如何在分组条形图上添加 p 值
- branch - 100%覆盖需要多少个测试用例
- reactjs - 如何在单独的文件中使用 Framer Motion 错开儿童?
- google-apps-script - ContinuationToken 函数中途中断
- inno-setup - Inno Setup:当我在安装程序外部按下时光标不会改变
- c# - 如何在 c# 中使用 BouncyCastle 获取 Blowfish/ECB/NoPadding 的密码?
- database - 无法在 DataGrip 中刷新数据库及其表架构
- geopandas - Python统一两个地理系统