协议缓冲区 - 存储双数组、1D、2D 和 3D

发布于 2024-11-26 03:54:18 字数 63 浏览 0 评论 0原文

如何使用 Protocol buffer 存储双精度 (1D) 数组? 多维(2D 或 3D)密集数组怎么样?

How can be an array of double (1D) stored using protocol buffer?
What about multi-dimensional (2D or 3D) dense arrays?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无语# 2024-12-03 03:54:18

人们可以简单地模仿 C/C++ 内存布局:

message DoubleMatrix {
  required uint32 rows = 1;
  required uint32 cols = 2;
  repeated double data = 3 [packed=true];
}

要访问数据,请使用 data[i*cols+j](行优先)或 data[i+rows*j] (列主)。
对于方阵,只需存储/之一。从技术上讲,即使在矩形的情况下,protobuf 也会知道数据的长度,并且可以导出其他值。

为了便于使用,人们可能会使用 Adapter 类将 Matrix 包装在 C++ 中,该类允许通过 double MatrixAdapter::get(int row, int col) 进行访问;它还可以验证data_size()==rows()*cols()

One could simply mimic the C/C++ memory layout:

message DoubleMatrix {
  required uint32 rows = 1;
  required uint32 cols = 2;
  repeated double data = 3 [packed=true];
}

To access the data, use data[i*cols+j] (row-major), or data[i+rows*j] (column-major).
For square matrices only one of rows/cols has to be stored. Technically even in the rectangular case protobuf will know the length of the data, and the other value can be derived.

For ease of use one would probably wrap the Matrix in C++ with an Adapter class that allows access via double MatrixAdapter::get(int row, int col); it could also verify data_size()==rows()*cols().

固执像三岁 2024-12-03 03:54:18

双精度数组最好通过

repeated double foo = 5 [packed=true];

重复存储,使其充当列表,允许多个项目; packed 避免了每个项目都有一个标题。

protobuf 中不直接支持矩形(或更大)数组。最接近的是存储类似的内容:

repeated innerType foo = 5; // note, can't be "packed"

message innerType {
    repeated double foo = 1 [packed=true];
}

这大致类似于锯齿状数组,但每层之间都有一个元素。

An array of double would be best stored via

repeated double foo = 5 [packed=true];

repeated makes it act as a list, allowing multiple items; packed avoids a header per item.

There is no direct support for rectangular (or higher) arrays in protobuf. The closest is to store something like:

repeated innerType foo = 5; // note, can't be "packed"

message innerType {
    repeated double foo = 1 [packed=true];
}

this is broadly akin to a jagged array, but with an element between each tier.

甜味超标? 2024-12-03 03:54:18

如果您的主要目标是更密集的 JSON 表示,您可以使用“众所周知的类型”[google.protobuf.ListValue][1] 作为第二个维度:

import "google/protobuf/struct.proto";
message DoubleMatrix {
  uint32 cols = 1;
  uint32 rows = 2;
  repeated google.protobuf.ListValue values = 3;
}

这将在将数据编组为 JSON 时生成一个数组数组。

{
  "cols": 2,
  "rows": 2,
  "values": [[1, 2], [3, 4]]
}

缺点是 ListValue 类型在内部使用内部类型,该内部类型对值使用 one-of 模式。在源代码中处理这可能比在没有所有魔法的情况下使用您自己的内部类型更麻烦。

[1] https://developers.google .com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.ListValue

If your main goal is a denser JSON representation, you could use the "well known type" [google.protobuf.ListValue][1] for the second dimension:

import "google/protobuf/struct.proto";
message DoubleMatrix {
  uint32 cols = 1;
  uint32 rows = 2;
  repeated google.protobuf.ListValue values = 3;
}

This will produce an array of arrays when marshaling the data to JSON.

{
  "cols": 2,
  "rows": 2,
  "values": [[1, 2], [3, 4]]
}

The downside is that the ListValue type internally uses an inner type that uses the one-of pattern for the values. This may be more cumbersome to handle in your source code than using your own inner type without all the magic.

[1] https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.ListValue

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文